[Java] Quando lancio + JAR da console, ognuno gira isolato in una sua JVM o no?

Matrixbob

Utente Attivo
34
0
CPU
Intel Q8200
Scheda Madre
Asus P5Q
HDD
Western Digital x2, Segate x 1
RAM
Corsair CM2X 1GB x2
GPU
Asus HD 5770 1GB
Audio
Realtek integrato
Monitor
Philips LCD
PSU
Energon 750W
Case
Middle tower troppo pesante
OS
Win e Lin
Quando lancio + JAR da console, ognuno gira isolato in una sua JVM o no?
Chiedo perchè nel caso NON fosse 1 lancio .JAR --> 1 JVM, allora dovrei fare attenzione ad usare variabili statiche di classe, giusto?
Potrei andarmi a sovrascrivere i dati come un pirla.

Voi sapete sta cosa?
TNX a lot!
 
D

deleted_98961

Ospite
Mi domando se conosci come è strutturata la gerarchia utilizzata dalla "macchina virtuale" di Java.
Prova a vedere qui: Mokabyte Numero 10 - Luglio 1997 - LA PIATTAFORMA JAVA
l'articolo è vecchiotto ma da un'idea. Su quel sito/rivista ci sono anche altre informazioni.

Dopo aver letto quell'articolo, qual è la risposta secondo te?
 

Matrixbob

Utente Attivo
34
0
CPU
Intel Q8200
Scheda Madre
Asus P5Q
HDD
Western Digital x2, Segate x 1
RAM
Corsair CM2X 1GB x2
GPU
Asus HD 5770 1GB
Audio
Realtek integrato
Monitor
Philips LCD
PSU
Energon 750W
Case
Middle tower troppo pesante
OS
Win e Lin
Pare che tutte le applicazioni girino sulla stessa JVM, ma nulla vieta di avere una macchina software dedicata per un applicativo no? Infatti ho trovato in giro un java -jar file.jar.
Risulta?
 
D

deleted_98961

Ospite
ma nulla vieta di avere una macchina software dedicata per un applicativo no?
Non capisco cosa tu intenda.
Forse non conosci la strutturazione e la gerarchia di un sistema operativo. Per questo motivo hai questo dubbio.
La JVM è di per sè un interprete. Uno strato software che interpreta un particolare codice indipendente dall'architettura e dal sistema operativo (il Bytecode, una codice intermedio) con in aggiunta molte cose luccicanti (stack, garbage collector, api,...).

Quando avvii un binario Java (.jar se vuoi) "semplicemente" crei una nuovo task, che non c'entra con Java, ma dipendente dal sistema operativo inizializzando un ambiente di lavoro. Questo task a dentro di se il codice per avviare l'interpete JVM che tradurra il codice java il linguaggio macchina (è più complicato di così, pensa solo alla gestione della memoria di Java).

Infatti ho trovato in giro un java -jar file.jar.Risulta?
rispiega questo punto.
 

Matrixbob

Utente Attivo
34
0
CPU
Intel Q8200
Scheda Madre
Asus P5Q
HDD
Western Digital x2, Segate x 1
RAM
Corsair CM2X 1GB x2
GPU
Asus HD 5770 1GB
Audio
Realtek integrato
Monitor
Philips LCD
PSU
Energon 750W
Case
Middle tower troppo pesante
OS
Win e Lin
Boh tutto può essere, allora, la racconto come la so io.

Ho capito che la JVM è implementata come interprete, ma è a tutti gli effetti una macchina virtuale.
Le variabili di classe, quelle static tanto per esser chiari, sono variabili consivise tra tutte le istanze di quella classe specifica in tutta la JVM in esecuzione.
Quindi ho il rischio di sporcare lettura e scrittura di queste variabili.
Quindi mi stavo chiedevo se era possibile ovviare a questo problema lanciando 1a1 primo.jar --> jvm1, secondo.jar -->jvm2, etc ... Isolando la computazione de facto.

Questo "shell> java -jar file.jar" pare proprio l'attuazione di quanto sopra descritto.

Per ogni java -jar pippo.jar è istanziata una nuova jvm. Anche se "pippo.jar" è lo stesso, ognuna ha la sua fettona di memoria, classi nominalmente identiche sono entità diverse e non interagiscono.
 
Ultima modifica:
D

deleted_98961

Ospite
Ho capito che la JVM è implementata come interprete, ma è a tutti gli effetti una macchina virtuale.
ok, tieni conto ancora che è uno strato del Sistema Operativo, è un ospite.
Le variabili di classe, quelle static tanto per esser chiari, sono variabili consivise tra tutte le istanze di quella classe specifica in tutta la JVM in esecuzione.
Quindi ho il rischio di sporcare lettura e scrittura di queste variabili.
Sono istanze nell'eseguibile, ma non sono condivise in TUTTA la JVM.
Se avvii un eseguibile C che ha delle variabili globali (non-static), che forse ti è più familiare, in più shell secondo te le varibili andranno in conflitto nell'OS? (PS: parliamo di layer utente, layer kernel è un altro mondo).


Quindi mi stavo chiedevo se era possibile ovviare a questo problema lanciando 1a1 primo.jar --> jvm1, secondo.jar -->jvm2, etc ... Isolando la computazione de facto.

Questo "shell> java -jar file.jar" pare proprio l'attuazione di quanto sopra descritto.
Per ogni java -jar pippo.jar è istanziata una nuova jvm. Anche se "pippo.jar" è lo stesso, ognuna ha la sua fettona di memoria, classi nominalmente identiche sono entità diverse e non interagiscono.
ok, la JVM è unica, ma ogni applicativo ha la sua fetta di memoria indipendente.


Devi sostituire "istanza di una nuova jvm" con "un'istanza di un'applicazione java che utilizza la UNICA jvm".

Quello che dici sulle static o le variabili di classe non ha senso. Quando lanci l'eseguibile java si crea un nuovo ambiente pulito Java che ha scope solo in questo ambiente. Non puoi interagire con altre classi che hai lanciato in un altro ambiente; ovvio se utilizzi artifizzi ad-hoc come tunnelling, socket, ovvio che puoi interagire, ma sono veri e proprie unità monolitiche.
Una variabile static di un eseguibile, con lo stesso nome di un altro eseguibile, non andranno mai in conflitto perchè sono indipendenti.
 

Matrixbob

Utente Attivo
34
0
CPU
Intel Q8200
Scheda Madre
Asus P5Q
HDD
Western Digital x2, Segate x 1
RAM
Corsair CM2X 1GB x2
GPU
Asus HD 5770 1GB
Audio
Realtek integrato
Monitor
Philips LCD
PSU
Energon 750W
Case
Middle tower troppo pesante
OS
Win e Lin
Ma come è possibile quello che dici se io ho un unico logger Log4j e tutti i jar paralleli che lancio infilano le loro righe sull'unico file di log?

static String nomeClasse = ImportManager.class.getName();
static Logger logger = Logger.getLogger(nomeClasse);

PS: ma dove ho scritto "istanza di una nuova jvm"?

DOMANDA:
Quindi tu mi garantisci che jar in esecuzione diversi non vanno a ropersi le palle uno con l'altro ma sono de facto isolati nella memoria?
 
Ultima modifica:

Matrixbob

Utente Attivo
34
0
CPU
Intel Q8200
Scheda Madre
Asus P5Q
HDD
Western Digital x2, Segate x 1
RAM
Corsair CM2X 1GB x2
GPU
Asus HD 5770 1GB
Audio
Realtek integrato
Monitor
Philips LCD
PSU
Energon 750W
Case
Middle tower troppo pesante
OS
Win e Lin
Confermo che i jar girano isolati come memoria, mentre l'id del thread si ripete per esecuzioni differenti e nel mio caso quindi NON è descripante.

immaginejn.jpg
 
D

deleted_98961

Ospite
Confermo che i jar girano isolati come memoria,
Non è il Jar perchè è un contenitore, ma è l'eseguibile che viene creato dalla chiamata java -jar ...

mentre l'id del thread si ripete per esecuzioni differenti
ogni eseguibile di qualunque natura, crea un nuovo task (thread, processo, dipende dall'ambito e dall'OS) con un PID univoco, non c'entra Java.

Ma come è possibile quello che dici se io ho un unico logger Log4j e tutti i jar paralleli che lancio infilano le loro righe sull'unico file di log?
questo può essere dovuto forse ad una mal posta configurazione o perchè sei nello stesso package o dall'IDE. Non saprei il motivo.
con jar paralleli intendi avvii dello stesso programma in diverse shell? non programmi concorrenti...

DOMANDA:Quindi tu mi garantisci che jar in esecuzione diversi non vanno a ropersi le palle uno con l'altro ma sono de facto isolati nella memoria?
non posso garantirti nulla. E' così che funziona la cooperazione tra strato della JVM (contenuto nel JRE) e del Sistema operativo, e dell'esecuzione di codice Java.
L'isolamento è dovuto sia alla struttura Task (Thread) del sistema operativo, che dall'istanzeazione dei una nuova applicazione Java che richiama lo strato della JVM.

su wiki.en c'è un'immagine che forse ti può chiarire l'idea del perchè c'è l'isolamento (a scanso, come detto, di artefatti ad-hoc come programmi concorrenti, socket, tunneling..., che condividono risorse):

500px-Java_virtual_machine_architecture.svg.png
 

Matrixbob

Utente Attivo
34
0
CPU
Intel Q8200
Scheda Madre
Asus P5Q
HDD
Western Digital x2, Segate x 1
RAM
Corsair CM2X 1GB x2
GPU
Asus HD 5770 1GB
Audio
Realtek integrato
Monitor
Philips LCD
PSU
Energon 750W
Case
Middle tower troppo pesante
OS
Win e Lin
Si intendo esecuzione dei jar da shell diverse, non faccio riferimento ai thread java, ma a quanto pare ai thread del SO. Chissà se poi i thread java vengono mappati nei thread di SO, boh...

CMQ devi garantirmi qualcosa, se asserisci hai le prove che lo dimostrano no? :)

Le img che posti sono sempre troppo generiche e accademiche, in realtà non corroborano/falsificano il teorema.
 
D

deleted_98961

Ospite
Si intendo esecuzione dei jar da shell diverse, non faccio riferimento ai thread java, ma a quanto pare ai thread del SO.
Sì certo se non li crei te nel tuo codice (Java-Thread) tale struttura non esiste.
Nel tipo di esecuzione che fai, allora, l'isolamento DEVE essere garantito, essendo thread diversi (del sistema operativo).


Chissà se poi i thread java vengono mappati nei thread di SO, boh...
sì dovrebbe esserci una mappatura, non ricordo quale sia quella utilizzata. Mi pare comunque che non collidono propriamente (1:1), dovrebbe essere struttura molti-uno (comunque |Java-Thread| > |OS-Thread|).

CMQ devi garantirmi qualcosa, se asserisci hai le prove che lo dimostrano no? :)
devo dirti che mi stai facendo venire qualche dubbio. Non sull'isolamento dei processi, ma più sul comportamento di Java.
Le variabili statiche (non accesso alla memoria, ma più su delle possibile collisioni sui nomi; di solito questi problemi si dovrebbero incontrare in ambienti concorrenti NON i ambienti single-thread come in queso caso.) e che ci siano più istanze di una JVM edulcorata che si poggia su una struttura più snella. Nel senso che forse nelle ultime versioni hanno cambiato paradigma.

Cerco qualche riferimento, ti farò sapere :)
 
D

deleted_98961

Ospite
Allora il riferimento migliore è il sito della Sun (Oracle): Chapter*5.*Loading, Linking, and Initializing

Per ogni eseguibile java (perciò task/processo dell'OS, per capirci, shell separate) viene eseguita una nuova istanza JVM. Lo strato che dicevo è spostato tutto (non solo in parte come pensavo) ad ogni nuovo programma.
Perciò è unica per ogni applicazione, ma comune se si lavora con Java-Thread (come ovvio che sia). Da intendere solo la JVM è istanziata, le api ed il resto sono ovviamente comuni a tutti.

Ma anche alla luce di ciò, alla fine, se non ci fosse l'isolamento per ogni eseguibile, lo spazio dei nomi ad es. sarebbe in confilitto ogni volta con un programma scritto da chissàchi.

Ammetto di aver avuto finora un'idea, in parte, sbagliata della struttura di Java. Mi dispiace di sto giro di post, il tuo dubbio è stato utile pure a me :)
 
Ultima modifica da un moderatore:

Matrixbob

Utente Attivo
34
0
CPU
Intel Q8200
Scheda Madre
Asus P5Q
HDD
Western Digital x2, Segate x 1
RAM
Corsair CM2X 1GB x2
GPU
Asus HD 5770 1GB
Audio
Realtek integrato
Monitor
Philips LCD
PSU
Energon 750W
Case
Middle tower troppo pesante
OS
Win e Lin
;) notte e tnx
 

Matrixbob

Utente Attivo
34
0
CPU
Intel Q8200
Scheda Madre
Asus P5Q
HDD
Western Digital x2, Segate x 1
RAM
Corsair CM2X 1GB x2
GPU
Asus HD 5770 1GB
Audio
Realtek integrato
Monitor
Philips LCD
PSU
Energon 750W
Case
Middle tower troppo pesante
OS
Win e Lin
C'è modo di vedere tipo con jconsole.exe l'andazzo specifico dei 3D e della VM in generale?
 
D

deleted_98961

Ospite
C'è modo di vedere tipo con jconsole.exe l'andazzo specifico dei 3D e della VM in generale?
strumenti del genere ci sono negli IDE se gli utilizzi, es. in NetBeans nativamente (che penso si appoggi su java console), ma dipende da cosa tu intenda con "andazzo"; se sapere cosa accade nella memoria, il debugger è un app praticamente necessaria in qualunque IDE che si rispetti.

Ma proprio utilizzando Java Console se cerchi nei doc di Oracle trovi del materiale:
- Using JConsole to Monitor Applications
- jvmstat (questo per le performance mi pare)

- JVM Monitor home (applicazione esterna)
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!