java垃圾收集在对话框中

前端之家收集整理的这篇文章主要介绍了java垃圾收集在对话框中前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
*当我尝试在JFrame中创建一个按钮时,我现在遇到一个非常奇怪的 java GC问题,当我单击该按钮时,它会显示需要处理并显示一些图像并需要近200M内存的JDialog.但问题是当我关闭对话框并重新打开它时,有时它会导致java.lang.OutOfMemoryError. (不是每次都)

试图解决这个问题,我简化了这个问题并做了一些实验,这让我更加困惑.

我在“实验”中使用的代码如下所示.
当我单击一个框架中的一个按钮时,我为一个整数数组分配160M内存,并显示一个对话框,但如果我关闭该对话框并重新打开它,则会出现OutOfMemoryError.我调整代码,结果是:

>如果我没有创建对话框并显示它,没有内存问题.
>如果我添加一个调用System.gc()的windowsCloseListener到对话框,没有内存问题.
>如果我在run()方法调用System.gc(),则会出现内存问题.

  1. public class TestController {
  2. int[] tmp;
  3.  
  4. class TDialog extends JDialog {
  5. public TDialog() {
  6. super();
  7. this.setDefaultCloSEOperation(JDialog.DISPOSE_ON_CLOSE);
  8. // If I uncommment this code,OutOfMemoryError seems to dispear in this situation
  9. // But I'm sure it not a acceptable solution
  10. /*
  11. this.addWindowListener(new WindowAdapter() {
  12. public void windowClosing(WindowEvent e) {
  13. System.out.println("windowsclose");
  14. TDialog.this.dispose();
  15. System.gc();
  16. }
  17. });
  18. */
  19. }
  20. }
  21.  
  22. TDialog dia;
  23.  
  24. public void run() {
  25. // If I do System.gc() here,OutOfMemoryError still exist
  26. // System.gc();
  27. tmp = new int[40000000];
  28. for (int i = 0; i < tmp.length; i += 10)
  29. tmp[i] = new Random().nextInt();
  30.  
  31. dia = new TDialog();
  32. dia.setVisible(true);
  33. }
  34.  
  35. public static void main(String[] args) {
  36. EventQueue.invokeLater(new Runnable() {
  37. @Override
  38. public void run() {
  39. final JFrame frame = new JFrame("test");
  40. frame.setDefaultCloSEOperation(JFrame.DISPOSE_ON_CLOSE);
  41. frame.setLocationRelativeTo(null);
  42. frame.setSize(200,200);
  43.  
  44. JButton button = new JButton("button");
  45. button.addActionListener(new ActionListener() {
  46. @Override
  47. public void actionPerformed(ActionEvent e) {
  48. TestController controller = new TestController();
  49. controller.run();
  50. controller = null;
  51. }
  52. });
  53.  
  54. frame.add(button);
  55. frame.setVisible(true);
  56. }
  57. });
  58. }
  59. }

我读过很多描述java的GC工作原理的文章.我认为如果java试图在堆中分配一些空间并且没有足够的可用空间,java将执行gc,并且如果无法通过“GC graph”从gc根访问对象,其中有一个边缘来自u表示你有一个对v的引用,root是一个线程工作栈中的东西,或者是本机资源,它是无用的,有资格被java的GC收集.

现在问题是当我单击按钮并尝试创建一个Integer数组时,我上次创建的Integer数组肯定有资格被java的GC收集.那么为什么它会导致错误.

为这样一个长篇描述道歉…我在提出问题时没有太多的策略,所以只是试图说清楚.

此外,我用来启动jvm的参数是“java -Xmx256m”

解决方法

您之前分配新的int [40000000],而tmp仍保留对最后一个int [40000000]的引用.
像tmp = new int [40000]这样的表达式中的操作顺序是:

> new int [40000]
>将对数组的引用分配给tmp

所以在1. tmp仍然保持对它的最后一个值的引用.

尝试做:

  1. tmp = null;
  2. tmp = new int[40000000];

猜你在找的Java相关文章