Java JCombobox内存泄漏,即使根本没有被引用?
也许你们中的一些人可以帮助我解决java和JComboxes的一个非常奇怪的问题。我试了几个小时来找出这个问题,但找不到解决办法。我不想在这里粘贴大量代码,但这个简单的循环演示了这一点:Java JCombobox内存泄漏,即使根本没有被引用?,java,swing,memory-leaks,jcombobox,garbage,Java,Swing,Memory Leaks,Jcombobox,Garbage,也许你们中的一些人可以帮助我解决java和JComboxes的一个非常奇怪的问题。我试了几个小时来找出这个问题,但找不到解决办法。我不想在这里粘贴大量代码,但这个简单的循环演示了这一点: JComboBox cb; for(int i=0;i<1000;i++) { cb=new JComboBox(); } JComboBox cb; 对于(int i=0;iJComboBox创建了一个带有combobox侦听器的DefaultListM
JComboBox cb;
for(int i=0;i<1000;i++)
{
cb=new JComboBox();
}
JComboBox cb;
对于(int i=0;iJComboBox创建了一个带有combobox侦听器的DefaultListModel。因此,对这样一个对象集群的垃圾收集被推迟。但是,在与我一起运行第四次之后,垃圾被收集,或者JIT发现它不需要创建这些对象
也许您的问题是显式调用System.gc()
没有清理它?我可以想象得到
*如何追踪问题
我尝试了以下方法来排除组件
private static class ReducedJComboBox<T> extends JComboBox<T> {
@Override
public void setEditor(ComboBoxEditor anEditor) {
}
}
public static void main( String[] args )
{
System.out.println("; " + Runtime.getRuntime().freeMemory());
long t0 = System.currentTimeMillis();
ComboBoxModel model = new DefaultComboBoxModel();
ComboBoxEditor editor = new ComboBoxEditor() {
public Component getEditorComponent() {
throw new UnsupportedOperationException("Not supported yet.");
}
public void setItem(Object anObject) {
}
public Object getItem() {
throw new UnsupportedOperationException("Not supported yet.");
}
public void selectAll() {
}
public void addActionListener(ActionListener l) {
}
public void removeActionListener(ActionListener l) {
}
};
JComboBox cb;
for (int i = 0; i < 1000; i++) {
cb = new JComboBox();
cb.setModel(model);
cb.setEditable(false);
cb.setEditor(editor);
}
long dt = t0 - System.currentTimeMillis();
System.out.println("dt=" + dt + " ms; " + Runtime.getRuntime().freeMemory());
System.gc();
System.out.println("finally " + Runtime.getRuntime().freeMemory());
}
私有静态类ReducedJComboBox扩展了JComboBox{
@凌驾
公共void集合编辑器(ComboBoxEditor anEditor){
}
}
公共静态void main(字符串[]args)
{
System.out.println(“;”+Runtime.getRuntime().freemory());
长t0=System.currentTimeMillis();
ComboBoxModel=新的DefaultComboxModel();
ComboBoxEditor editor=新建ComboBoxEditor(){
公共组件getEditorComponent(){
抛出新的UnsupportedOperationException(“尚未支持”);
}
public void setItem(对象anObject){
}
公共对象getItem(){
抛出新的UnsupportedOperationException(“尚未支持”);
}
public void selectAll(){
}
public void addActionListener(ActionListener l){
}
公共void removeActionListener(ActionListener l){
}
};
JComboBox cb;
对于(int i=0;i<1000;i++){
cb=新的JComboBox();
cb.setModel(model);
cb.setEditable(假);
cb.setEditor(编辑);
}
long dt=t0-System.currentTimeMillis();
System.out.println(“dt=“+dt+”ms;“+Runtime.getRuntime().freemory());
gc();
System.out.println(“finally”+Runtime.getRuntime().freemory());
}
JComboBox创建了一个带有combobox侦听器的DefaultListModel。因此,对这样一个对象集群的垃圾收集被推迟。但是,在与我一起运行第四次之后,垃圾被收集,或者JIT发现它不需要创建这些对象
也许您的问题是显式调用System.gc()
没有清理它?我可以想象得到
*如何追踪问题
我尝试了以下方法来排除组件
private static class ReducedJComboBox<T> extends JComboBox<T> {
@Override
public void setEditor(ComboBoxEditor anEditor) {
}
}
public static void main( String[] args )
{
System.out.println("; " + Runtime.getRuntime().freeMemory());
long t0 = System.currentTimeMillis();
ComboBoxModel model = new DefaultComboBoxModel();
ComboBoxEditor editor = new ComboBoxEditor() {
public Component getEditorComponent() {
throw new UnsupportedOperationException("Not supported yet.");
}
public void setItem(Object anObject) {
}
public Object getItem() {
throw new UnsupportedOperationException("Not supported yet.");
}
public void selectAll() {
}
public void addActionListener(ActionListener l) {
}
public void removeActionListener(ActionListener l) {
}
};
JComboBox cb;
for (int i = 0; i < 1000; i++) {
cb = new JComboBox();
cb.setModel(model);
cb.setEditable(false);
cb.setEditor(editor);
}
long dt = t0 - System.currentTimeMillis();
System.out.println("dt=" + dt + " ms; " + Runtime.getRuntime().freeMemory());
System.gc();
System.out.println("finally " + Runtime.getRuntime().freeMemory());
}
私有静态类ReducedJComboBox扩展了JComboBox{
@凌驾
公共void集合编辑器(ComboBoxEditor anEditor){
}
}
公共静态void main(字符串[]args)
{
System.out.println(“;”+Runtime.getRuntime().freemory());
长t0=System.currentTimeMillis();
ComboBoxModel=新的DefaultComboxModel();
ComboBoxEditor editor=新建ComboBoxEditor(){
公共组件getEditorComponent(){
抛出新的UnsupportedOperationException(“尚未支持”);
}
public void setItem(对象anObject){
}
公共对象getItem(){
抛出新的UnsupportedOperationException(“尚未支持”);
}
public void selectAll(){
}
public void addActionListener(ActionListener l){
}
公共void removeActionListener(ActionListener l){
}
};
JComboBox cb;
对于(int i=0;i<1000;i++){
cb=新的JComboBox();
cb.setModel(model);
cb.setEditable(假);
cb.setEditor(编辑);
}
long dt=t0-System.currentTimeMillis();
System.out.println(“dt=“+dt+”ms;“+Runtime.getRuntime().freemory());
gc();
System.out.println(“finally”+Runtime.getRuntime().freemory());
}
我使用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");
}
} );
}
}
因此,是的,在我的机器上,我可以通过AppContext
中的一个引用得出结论,JComboBox仍然存在于内存中。搜索该引用会导致我们找到。我尝试使用您的语句通过while循环将JConsole连接到一个主方法。不幸的是,我的主程序在JConsole成功之前抛出了一个OutOfMemoryException
nect,所以我无法像垃圾神在他的回答中那样生成一幅漂亮的图片。我尝试使用NBTestCase#assertGC
方法使用一个简单的测试用例。该方法的好处是,在内存泄漏的情况下打印出对正在检查的对象的强引用。它还通过用哑byt填充堆来触发GCe数组,强制GC启动
i can do this code where ever i wont the 1000 ComboBoxes are never GCed
and i do not get it, why
我使用的非常简单的测试用例
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");
}
} );
}
}
因此,是的,在我的机器上,我可以通过AppContext
中的一个引用得出结论,JComboBox仍然存在于内存中。搜索该引用会导致我们找到。我尝试使用您的语句通过while循环将JConsole连接到一个主方法。不幸的是,我的主程序在JConsole成功之前抛出了一个OutOfMemoryException
nect,所以我不能像垃圾神在他的回答中那样画出一张漂亮的照片
i can do this code where ever i wont the 1000 ComboBoxes are never GCed
and i do not get it, why
答案可能是,如果不存在对该对象的另一个引用,可能会对非常简单的对象进行GC'ed,或者另一个问题可能是您引用了静态对象(从不GC'ed只能取null值),或者您的对象是静态的
答案可能是,如果不存在对该对象的另一个引用,那么可能会对非常简单的对象进行GC'ed,或者另一个问题可能是您引用了静态对象(从不GC'ed只能取null值),或者您的对象是静态的Do y