Я пытался с помощью простого тестового примера, используя метод NBTestCase#assertGC
.Преимущество этого метода в том, что он распечатывает сильные ссылки на объект, который вы проверяете в случае утечки памяти.Он также запускает GC, заполняя кучу массивом немых байтов, заставляя GC запускаться.
Очень простой тестовый пример, который я использовал
public class ComboBoxMemoryLeak {
public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
@Override
public void run() {
List<WeakReference<JComboBox>> references = new ArrayList<WeakReference<JComboBox>>( );
JComboBox comboBox;
for (int i = 0; i < 1000; i++ ){
comboBox = new JComboBox( );
references.add( new WeakReference<JComboBox>( comboBox ) );
}
comboBox = null;
for ( int i = 0, referencesSize = references.size(); i < referencesSize; i++ ) {
System.out.println( "i = " + i );
WeakReference<JComboBox> weakReference = references.get( i );
NbTestCase.assertGC( "Combobox", weakReference );
}
System.out.println("No memory leak found");
}
} );
}
}
, приводящий к следующей трассировке на моем Macработает с JDK1.6
i = 0
Exception in thread "AWT-EventQueue-0" junit.framework.AssertionFailedError: Combobox:
private static sun.awt.AppContext sun.awt.AppContext.mainAppContext->
sun.awt.AppContext@30f7f540-table->
java.util.HashMap@c324b85-table->
[Ljava.util.HashMap$Entry;@770fba26-[8]->
java.util.HashMap$Entry@63adf08f-value->
java.beans.PropertyChangeSupport@4f1b8540-children->
java.util.Hashtable@2305454a-table->
[Ljava.util.Hashtable$Entry;@4a9a4ba3-[0]->
java.util.Hashtable$Entry@6aed0f19-value->
java.beans.PropertyChangeSupport@23597cac-listeners->
sun.awt.EventListenerAggregate@2f39c244-listenerList->
[Ljava.beans.PropertyChangeListener;@2e2e06bd-[0]->
javax.swing.JViewport$1@2a72cf60-this$0->
javax.swing.JViewport@2b9c1dc4-parent->
javax.swing.JScrollPane@b99f7c6-parent->
com.apple.laf.AquaComboBoxPopup@6699166f-comboBox->
javax.swing.JComboBox@3bc634b9
at junit.framework.Assert.fail(Assert.java:50)
at org.netbeans.junit.NbTestCase$4.run(NbTestCase.java:1351)
at org.netbeans.junit.internal.NbModuleLogHandler.whileIgnoringOOME(NbModuleLogHandler.java:143)
at org.netbeans.junit.NbTestCase.assertGC(NbTestCase.java:1309)
at org.netbeans.junit.NbTestCase.assertGC(NbTestCase.java:1285)
at ComboBoxMemoryLeak$1.run(ComboBoxMemoryLeak.java:32)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:677)
at java.awt.EventQueue.access$000(EventQueue.java:85)
at java.awt.EventQueue$1.run(EventQueue.java:638)
at java.awt.EventQueue$1.run(EventQueue.java:636)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:647)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Так что да, на моей машине я бы пришел к выводу, что JComboBox все еще присутствует в памяти через ссылку в AppContext
.Поиск этого ведет нас к этому ТАКОМУ вопросу .Я попытался подключить JConsole к методу main с помощью цикла while с вашим оператором.К сожалению, моя основная программа выдавала OutOfMemoryException
до того, как JConsole смог подключиться, поэтому я не смог сгенерировать красивую картинку, как trashgod в своем ответе.