Domanda

Dati questi due comandi

A:

$ java -Xms10G -Xmx10G myjavacode input.txt

B:

$ java -Xms5G -Xmx5G myjavacode input.txt

Ho due domande:

  1. Poiché il comando A riserva più memoria con i suoi parametri, A funzionerà più velocemente di B?
  2. In che modo -Xmx e -Xms influenzano il processo in esecuzione e l'output del mio programma?
È stato utile?

Soluzione

Dipende dal GC utilizzato da Java. GC paralleli potrebbero funzionare meglio con impostazioni di memoria più grandi, ma non ne sono esperto.

In generale, se hai una memoria più grande, meno frequente deve essere GC-ed - c'è molto spazio per la spazzatura. Tuttavia, quando si tratta di un GC, il GC deve lavorare su più memoria, che a sua volta potrebbe essere più lenta.

Altri suggerimenti

L'argomento -Xmx definisce la dimensione massima della memoria che l'heap può raggiungere per la JVM. Devi conoscere bene il tuo programma e vedere come funziona sotto carico e impostare questo parametro di conseguenza. Un valore basso può causare OutOfMemoryExceptions o prestazioni molto scarse se la memoria heap del programma sta raggiungendo la dimensione heap massima. Se il programma è in esecuzione su un server dedicato, è possibile impostare questo parametro su un valore superiore perché non influirà su altri programmi.

L'argomento -Xms imposta la dimensione iniziale della memoria heap per la JVM. Ciò significa che quando avvii il tuo programma, la JVM assegnerà immediatamente questa quantità di memoria. Ciò è utile se il programma consumerà una grande quantità di memoria heap fin dall'inizio. Ciò evita che JVM aumenti costantemente l'heap e possa ottenere alcune prestazioni lì. Se non sai se questo parametro ti aiuterà, non utilizzarlo .

In sintesi, questo è un compromesso che devi decidere basandoti solo sul comportamento della memoria del tuo programma.

Ho scoperto che in alcuni casi troppa memoria può rallentare il programma.

Ad esempio ho avuto un motore di trasformazione basato su ibernazione che ha iniziato a funzionare lentamente con l'aumentare del carico. Si è scoperto che ogni volta che ottenevamo un oggetto dal db, l'ibernazione controllava la memoria per oggetti che non sarebbero mai più stati utilizzati.

La soluzione era di eliminare i vecchi oggetti dalla sessione.

Stuart

  1. L'allocazione dipende sempre dal tuo sistema operativo. Se si alloca troppa memoria, si potrebbe finire per caricare porzioni in swap, il che in effetti è lento.
  2. Il funzionamento più lento o più rapido del programma dipende dai riferimenti che la VM deve gestire e pulire. Il GC non deve scorrere attraverso la memoria allocata per trovare oggetti abbandonati. Sa che sono gli oggetti e la quantità di memoria che allocano tramite la mappatura di riferimento. Quindi spazzare dipende solo dalle dimensioni dei tuoi oggetti. Se il tuo programma si comporta allo stesso modo in entrambi i casi, l'unico impatto sulle prestazioni dovrebbe essere all'avvio della VM, quando la VM tenta di allocare memoria fornita dal tuo sistema operativo e se usi lo swap (che porta di nuovo a 1.)

È difficile dire come l'allocazione della memoria influenzerà la tua velocità. Dipende dall'algoritmo di garbage collection utilizzato dalla JVM. Ad esempio, se il Garbage Collector deve mettere in pausa per eseguire una raccolta completa, quindi se si dispone di 10 memoria in più rispetto a quella realmente necessaria, il Collector avrà 10 rifiuti in più da ripulire.

Se stai usando java 6 puoi usare jconsole (nella cartella bin di jdk) per collegarti al tuo processo e guardare come si sta comportando il collector. In generale, i collezionisti sono molto intelligenti e non sarà necessario eseguire alcuna messa a punto, ma se ne hai bisogno ci sono numerose opzioni che hai usato per ottimizzare ulteriormente il processo di raccolta.

> C:\java -X

-Xmixed           mixed mode execution (default)
-Xint             interpreted mode execution only
-Xbootclasspath:<directories and zip/jar files separated by ;>
                  set search path for bootstrap classes and resources
-Xbootclasspath/a:<directories and zip/jar files separated by ;>
                  append to end of bootstrap class path
-Xbootclasspath/p:<directories and zip/jar files separated by ;>
                  prepend in front of bootstrap class path
-Xnoclassgc       disable class garbage collection
-Xincgc           enable incremental garbage collection
-Xloggc:<file>    log GC status to a file with time stamps
-Xbatch           disable background compilation
-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set java thread stack size
-Xprof            output cpu profiling data
-Xfuture          enable strictest checks, anticipating future default
-Xrs              reduce use of OS signals by Java/VM (see documentation)
-Xcheck:jni       perform additional checks for JNI functions
-Xshare:off       do not attempt to use shared class data
-Xshare:auto      use shared class data if possible (default)
-Xshare:on        require using shared class data, otherwise fail.

Le opzioni -X non sono standard e sono soggette a modifiche senza preavviso.

(copia-incolla)

Questa era sempre la domanda che avevo quando stavo lavorando su una mia applicazione che ha creato un numero enorme di thread per richiesta.

Quindi questa è davvero una bella domanda e ci sono due aspetti:
1. Se i miei valori Xms e Xmx devono essere uguali
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; - La maggior parte dei siti web e persino documenti di Oracle suggeriscono che sia la stessa. Tuttavia, suggerisco di avere circa il 10-20% di buffer tra questi valori per offrire un'opzione di ridimensionamento dell'heap all'applicazione in caso di picchi improvvisi di traffico intenso O di una perdita di memoria accidentale.

2. Se dovrei avviare la mia applicazione con una dimensione heap inferiore
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; - Quindi, ecco il punto - non importa quale GC Algo usi (anche G1), l'heap di grandi dimensioni ha sempre qualche compromesso. L'obiettivo è identificare il comportamento della tua applicazione in base alle dimensioni dell'heap che puoi consentire al GC di mettere in pausa in termini di latenza e velocità effettiva.
   & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; - Ad esempio, se la tua applicazione ha molti stack (ogni thread ha 1 MB di stack nella memoria nativa e non in heap) ma non occupa spazio pesante sugli oggetti, quindi suggerisco di avere un valore inferiore di Xms.
   & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; - Se la tua applicazione crea molti oggetti con un numero crescente di thread, identifica a quale valore di Xms tu può impostare per tollerare quelle pause STW. Ciò significa identificare il tempo di risposta massimo delle richieste in arrivo che è possibile tollerare e in base alla dimensione minima dell'heap.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top