2012-03-16 19 views
9

Gestirò un algoritmo genetico sul computer del mio coinquilino per l'intero weekend, e temo che possa esaurire la memoria per un periodo così lungo. Tuttavia, il mio algoritmo funziona in modo tale da rendere ragionevolmente facile tagliare i risultati meno utili, quindi se ci fosse un modo per dire quando il mio programma sta per esaurire lo spazio heap, potrei probabilmente fare spazio e andare avanti ancora un po 'di tempo.Un programma Java può rilevare che sta per esaurirsi nello spazio heap?

C'è un modo per essere avvisati quando la JVM sta esaurendo lo spazio heap, prima di OutOfMemoryError?

+0

possibile duplicato di [Come monitorare dinamicamente le dimensioni dell'heap Java?] (Http://stackoverflow.com/questions/2163228/how-to-dynamically-monitor-java-heap-size) –

+0

@Andreas_D, questa domanda tratta sul monitoraggio del programma esternamente. Voglio che il mio programma reagisca quando sta per esaurire lo spazio disponibile. – zneak

+0

le risposte all'altra domanda includono soluzioni di monitoraggio interne ed esterne. –

risposta

6

È possibile registrare un javax.management.NotificationListener che viene chiamato quando viene raggiunta una determinata soglia.

Qualcosa di simile

final MemoryMXBean memBean = ManagementFactory.getMemoryMXBean(); 
final NotificationEmitter ne = (NotificationEmitter) memBean; 

ne.addNotificationListener(listener, null, null); 

final List<MemoryPoolMXBean> memPools = ManagementFactory 
    .getMemoryPoolMXBeans(); 
for (final MemoryPoolMXBean mp : memPools) { 
    if (mp.isUsageThresholdSupported()) { 
    final MemoryUsage mu = mp.getUsage(); 
    final long max = mu.getMax(); 
    final long alert = (max * threshold)/100; 
    mp.setUsageThreshold(alert); 

    } 
} 

Dove ascoltatore è la propria implementazione di NotificationListener.

+0

Sembra molto simile a quello che vorrei. Lo proverò. – zneak

+0

Io uso questo approccio in http://code.google.com/p/pitestrunner/ se desideri un esempio. Cerca la classe MemoryWatchdog ed è utilizzata da MutationTestSlave. – henry

+0

Non dimenticare di aggiungere un filtro durante la sottoscrizione, ad esempio: NotificationFilter filter = x -> MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED.equals (x.getType()); ne.addNotificationListener (tryPreventOom, filter, null); –

3

Si può provare questo:

// Get current size of heap in bytes 
long heapSize = Runtime.getRuntime().totalMemory(); 

// Get maximum size of heap in bytes. The heap cannot grow beyond this size. 
// Any attempt will result in an OutOfMemoryException. 
long heapMaxSize = Runtime.getRuntime().maxMemory(); 

// Get amount of free memory within the heap in bytes. This size will increase 
// after garbage collection and decrease as new objects are created. 
long heapFreeSize = Runtime.getRuntime().freeMemory(); 

Come si trova qui - http://www.exampledepot.com/egs/java.lang/GetHeapSize.html

+0

Suppongo che questo potrebbe rendere un trucco ok, ma preferirei essere notificato automaticamente quando viene soddisfatta una certa soglia, piuttosto che dover eseguire il polling dello stato della memoria ad un dato intervallo (un po 'come le notifiche di memoria su iOS). – zneak

+0

Non sono a conoscenza di altri modi per ricevere notifiche automaticamente in base a una determinata soglia, a meno che non si scriva autonomamente un poller per farlo in background. – Nikhil

1

Basta utilizzare WeakReferences per i risultati discardable, allora saranno scartati, se necessario, per motivi di spazio.

+0

Non posso lasciarlo a discrezione del GC, in quanto ho bisogno di rivedere gli oggetti prima di decidere che siano eliminabili. – zneak

+0

+1: Oppure usa le SoftReference che sono più longeve, WeakReference vengono sempre scartate su un GC. È possibile mantenere un ReferenceQueue per ricevere una notifica dell'oggetto che potrebbe essere ripulito. –

0

Non sono sicuro, ma non è possibile risolvere il tuo scopo JConsole ??

Problemi correlati