在Java中,有一个嵌套的静态类Human
,我想知道在清除map
变量后是否可以使其可用于收集垃圾。在doSomeCode()
之前的那一刻,我调用System.gc()
并添加Thread.sleep(60000)
等待垃圾收集器获取未引用的map
内容,但没有办法 - 似乎{{1}生活在一个程序中,除非它要完成。我的问题是我需要释放内存,否则会得到map
。
您认为如何阻止OutOfMemoryError
类的map
属性被回收?是因为Human
类是静态的,因此它的所有成员都不能被垃圾收集?
Human
答案 0 :(得分:3)
从你写的地方h.map = null;
开始,地图就有资格使用GC(技术上不需要删除和清除)。
你没有看到它是GC的原因可能是因为你在同一个方法中运行所有代码,并且GC不必在方法退出之前收集局部变量。
如果你尝试将它拆分成几个方法,它将有助于GC(一旦方法退出,它将摆脱局部变量。)
另见this post。
ps:我假设你没有任何地方对地图内容或地图本身的引用!
答案 1 :(得分:2)
Human类是静态的这一事实没有任何意义 - 即使map
变量是静态的,将其设置为null也可以释放垃圾回收的对象内容。
如果您遇到OutOfMemoryErrors,并且您确定地图内容是原因,那么必须在某处对数据进行延迟引用。例如,如果我这样做:
human.map.put(0, new int[10000]);
something.thing = map.get(0);
human.map.remove(0);
human.map = null;
请注意,对int[10000]
的引用仍保留在内存中,@ something.thing
。清理地图只是释放数组以进行垃圾收集所需工作的一部分。
答案 2 :(得分:0)
请注意,内部static
类确实是顶级类,但只是在class
内,因此收集实例的GC规则与GC在公共类实例上应用的规则相同。
答案 3 :(得分:0)
System.gc()
之后无需睡眠 - 在垃圾收集器完成之前,gc方法不会返回。
为了垃圾回收的目的,静态内部类的实例被视为与任何其他类的实例相同。您正确地释放了人类的map
个元素(尽管调用map.remove()
和map.clear()
以及map = null
过于苛刻 - 只需要map = null
1} p>
答案 4 :(得分:0)
看起来您正在使用所有原始数据类型。这可能是一个问题,这只是一个理论,我没有测试过,但它可能值得一试。
尝试使用ArrayList,而不是使用int的数组(int [])。这应该创建可以被垃圾收集的对象,在堆栈上而不是在对象堆上创建原始数据类型,因此它们不受垃圾收集的影响?
注意:我提出了一个问号,因为我不是肯定的,有人可以证实或拒绝我的理论。
理论拒绝:(,离开其他人阅读
答案 5 :(得分:-3)
1)自从我用Java编程以来,已经有一段时间了,但我的猜测是静态对象/变量在整个程序执行期间的特殊位置。
2)明确调用GC不能确保删除对象。您只需调用GC并自行决定(并且您无法真正影响此行为)。