GC rilascia la memoria sul sistema operativo?

Quando il garbage collector viene eseguito e rilascia memoria, questa memoria torna al sistema operativo o viene mantenuta come parte del processo. Ho avuto la netta impressione che la memoria non sia mai stata effettivamente rilasciata sul sistema operativo, ma conservata come parte dell’area di memoria / pool per essere riutilizzata dallo stesso processo.

Di conseguenza, la memoria effettiva di un processo non diminuirà mai. Un articolo che mi ha ricordato è stato questo e Java Runtime è scritto in C / C ++ quindi suppongo che si applichi la stessa cosa?

Aggiornare
La mia domanda riguarda Java. Sto citando C / C ++ dal momento che presumo che l’allocazione / deallocazione di Java sia fatta da JRE usando qualche forma di malloc / delete

La JVM di HotSpot rilascia nuovamente la memoria nel sistema operativo, ma lo fa a malincuore dal momento che il ridimensionamento dell’heap è costoso e si presume che, se necessario, sarà necessario ricorrere a tale heap.

Puoi renderlo più aggressivo impostando -XX:GCTimeRatio=19 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30 che consentirà di dedicare più tempo alla CPU per raccogliere e limitare la quantità di memoria heap allocata ma non utilizzata dopo un ciclo GC.

Supponendo che tu stia utilizzando un collector simultaneo puoi anche impostare -XX:InitiatingHeapOccupancyPercent=N con N su un valore basso per consentire al GC di eseguire raccolte simultanee quasi ininterrottamente, il che consumerà ancora più cicli della CPU ma ridurrà l’heap prima. Questo in genere non è una buona idea, ma su alcuni tipi di macchine con molti core CPU di riserva ma con poca memoria può avere senso.

Se stai utilizzando un raccoglitore con un objective del tempo di pausa predefinito (CMS o G1) puoi anche rilassare l’objective di posizionare meno vincoli sul raccoglitore, oppure puoi passare al collettore parallelo per dare la priorità all’impaginazione sui tempi di pausa.

Inoltre con l’opzione Java 9 -XX:-ShrinkHeapInSteps può essere utilizzato per applicare in modo più aggressivo il restringimento causato dalle precedenti due opzioni. Rilevante bug OpenJDK .

Si noti che le capacità e il comportamento di restringimento dipendono dal garbage collector scelto. Ad esempio G1 ha guadagnato solo la capacità di restituire blocchi inutilizzati nel mezzo dell’heap con jdk8u20.

Quindi, se è necessaria la riduzione dell’heap, dovrebbe essere testato per una particolare versione di JVM e configurazione di GC.

La registrazione GC con PrintAdaptiveSizePolicy può anche fornire informazioni approfondite, ad esempio quando JVM tenta di utilizzare più memoria per la generazione giovane per raggiungere determinati obiettivi.

Esiste anche una bozza di JEP per fare in modo che G1 restituisca più memoria, ma essendo una bozza non è sicuro se e quando verrà implementata. Menziona anche Shenandoah e OpenJ9 VM che hanno l’abilità.

La JVM rilascia la memoria di riserva in alcune circostanze, ma (per motivi di prestazioni) ciò non accade ogni volta che un po ‘di memoria viene raccolta. Dipende anche da JVM, OS, garbage collector, ecc. Puoi guardare il consumo di memoria della tua app con JConsole, VisualVM o un altro profiler.

Vedi anche questa relazione sui bug

questo articolo spiega come funziona il GC in Java 7. In breve, ci sono molti diversi garbage collector disponibili. Di solito la memoria viene mantenuta per il processo Java e solo alcuni GC lo rilasciano al sistema (su richiesta, penso). Ma la memoria utilizzata dal processo Java non crescerà indefinitamente, poiché esiste un limite superiore definito dall’opzione Xmx (che di solito è 256m, ma penso che sia OS / macchina dipendente).