为什么Java垃圾收集器不收集垃圾? [英] Why doesn't the Java garbage collector collect garbage?

查看:100
本文介绍了为什么Java垃圾收集器不收集垃圾?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩着一个可怕的数据结构,它基本上是一棵树,每个节点都在 HashMap 对象中存储对其子元素的引用。我需要通过将这个后一个子树设置为新的根来摆脱根和除了一个以外的所有子树时释放内存。我认为这可能是我的数据结构中的一些错误,也许是我忘了在那里的一些引用,所以没有资格进行垃圾回收。但是我想先尝试一些更简单的方法,然后执行以下测试:

  import java.io.BufferedReader; 
import java.io.InputStreamReader;
import java.io.IOException;

public class MyNode {
MyNode next;
int somedata;

public MyNode(MyNode n){
next = n;
somedata = 0;


public static void main(String [] args)throws IOException {
MyNode p = new MyNode(null);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
for(int i = 0; i <10000000; i ++){
MyNode n = new MyNode(p);
p = n;
}
while(p!= null){
MyNode p1 = p.next;
p.next = null;
p = p1;
}
in.readLine();
}
}

主要到达 in时。 readline(),我可以在htop中看到该进程仍然有250MB左右的分配给自己,没有任何东西被释放。我显然首先试图简单地做< / p>

  p = null; 

而不是while循环。但它不起作用,所以我想出了以前的代码。

解决方案

你的问题有点不清楚 - 你真的得到OutOfMemoryError异常?你想要解决什么问题?有几个原因会让你看到你的测试用例表现出来的行为:


  1. 不再可以从GC根访问 - 它只是变得符合垃圾回收的条件。 GC通常只在分配失败时触发。由于你实际上没有在你的循环中分配内存来删除引用,所以GC完全有可能还没有运行。

  2. 当收集垃圾时,堆中的内存通常不会返回到操作系统 - 因此,从操作系统的角度来看它不会产生准确的答案。使用VisualVM或像jmap和jhat这样的工具将是找出堆中实际仍然存在的最佳方式。


I'm playing with a horrifying data structure which basically is a tree, and each node stores references to its children in a HashMap object. I'm having troubles freeing memory whenever I need to get rid of the root and all its subtrees except one, by setting this latter subtree as the new root. I thought it might be some bug in my data structure, maybe some reference that I forgot to be there, so nothing becomes eligible for garbage collection. But I wanted to try something much simpler first, and implemented the following test:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class MyNode {
        MyNode next;
        int somedata;

        public MyNode(MyNode n) {
            next = n;
            somedata = 0;
        }

        public static void main(String[] args) throws IOException {
            MyNode p = new MyNode(null);
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            for (int i=0; i<10000000; i++) {
                MyNode n = new MyNode(p);
                p = n;
            }
            while (p!=null) {
                MyNode p1 = p.next;
                p.next = null;
                p = p1;
            }
            in.readLine();
        }
}

When main reaches in.readline(), I can see in htop that the process still has 250MB or so allocated for itself, and nothing gets freed. I obviously first tried to simply do

p = null;

instead of the while loop. But it didn't work so I came up with the previous code.

解决方案

Your question is somewhat unclear - are you actually getting OutOfMemoryErrors? What are you trying to solve? There are a few reasons you are seeing the behavior manifested in your test case:

  1. Garbage isn't collected the moment something is no longer reachable from a GC root - it simply becomes eligible for garbage collection. GC typically is only triggered when there is an allocation failure. Since you aren't actually allocating anymore memory in your loop that nulls out the references, it is entirely possible the GC just hasn't run yet.

  2. Even when garbage is collected, the memory in the heap is typically not returned to the OS - so looking at it from the perspective of the OS will not yield an accurate answer. Using VisualVM or tools like jmap and jhat would be the best way to figure out what is actually still on the heap.

这篇关于为什么Java垃圾收集器不收集垃圾?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆