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");
}
} );
}
}
在我的使用 JDK1.6 运行的 Mac 上导致以下跟踪
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)
所以是的,在我的机器上,我会通过AppContext
. 搜索导致我们这个 SO question。我尝试使用您的语句将 JConsole 连接到带有 while 循环的 main 方法。不幸的是,我的主程序OutOfMemoryException
在 JConsole 连接之前抛出了一个错误,所以我无法像垃圾神在他的回答中那样生成一张漂亮的图片。