Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java System.gc不会在一次运行中清除。使用3个或更多呼叫进行清除_Java_Garbage Collection_Visualvm - Fatal编程技术网

Java System.gc不会在一次运行中清除。使用3个或更多呼叫进行清除

Java System.gc不会在一次运行中清除。使用3个或更多呼叫进行清除,java,garbage-collection,visualvm,Java,Garbage Collection,Visualvm,我正在JDK1.6中运行的java应用程序中测试堆大小的使用情况。我使用工具VisualVM来监视堆的使用情况。我发现在几分钟内,堆大小的最大使用量约为500 MB。我使用了选项“performgc”,它调用System.GC()。第一次使用它时,最大堆减少到410MB,然后再次使用它获得130MB,下一次使用它获得85MB。我连续打了四个电话,没有任何间隔。为什么调用System.gc()第一次没有收集到85MB的所有堆。这背后还有其他原因吗。或者我应该尝试其他方法?当所有对象扫描一次后,Sy

我正在JDK1.6中运行的java应用程序中测试堆大小的使用情况。我使用工具VisualVM来监视堆的使用情况。我发现在几分钟内,堆大小的最大使用量约为500 MB。我使用了选项“performgc”,它调用System.GC()。第一次使用它时,最大堆减少到410MB,然后再次使用它获得130MB,下一次使用它获得85MB。我连续打了四个电话,没有任何间隔。为什么调用System.gc()第一次没有收集到85MB的所有堆。这背后还有其他原因吗。或者我应该尝试其他方法?

当所有对象扫描一次后,System.gc()将返回

对象在收集后应最终确定()。大多数对象不实现此方法,但对于实现此方法的对象,它们将被添加到队列中,以便稍后清理。这意味着这些对象还无法清理(而不是保存它们的队列节点),即触发GC的行为可能会暂时增加内存消耗

此外,还有对GC可能清理或不清理的对象的软引用。我们的假设是,只有在没有清理太多其他内容的情况下,才应该清理这些内容

简而言之,并非所有对象都可以在一个周期内清理。

System.gc()请求JVM启动垃圾收集。如果您希望在System.GC()之后立即调用GC,那么这是一个错误的概念。多次打电话也无济于事。无法将System.gc()映射为实际的垃圾回收。另外,无论您调用System.gc()多少次,JVM都只在准备好执行gc时才执行gc。可能发生的情况是,即使使用了第一个System.gc(),堆大小也在减小,但并不是在您调用它的时候。与第一个System.gc()相关的垃圾收集可能会在后台完成,同时您的代码会到达第三个System.gc()语句


如果您非常确定只添加多个System.gc()有助于减少堆大小。然后,您需要检查在JVM中第一个和最后一个System.gc()之间创建的所有对象。可能还有其他线程创建对象。

一个可能的原因可能是使用了
java.lang.ref.Reference
类型。如果GC要破坏“引用”,这将在GC完成后发生。因此无法访问的任何对象都将留给下一个GC周期处理

最后定稿也是这样。如果一个对象需要完成,那么它和所有可以从中访问的对象(仅)很可能只能在下一个GC周期中收集

还有一个问题是,GC用于收缩堆的算法是非攻击性的。根据该页面,如果垃圾收集后超过70%的堆是空闲的,GC只会收缩堆。然而,这是否指完整的GC还不完全清楚。所以你可以让GC进行部分GC和收缩,然后是完整GC和收缩

(有些人从
System.gc()
javadocs的措辞推断它将执行完整的gc。然而,我怀疑这实际上是版本/gc相关的。)



但老实说,这一切都应该是毫无意义的。试图强迫应用程序返回尽可能多的内存是毫无意义的。很可能是您强制它丢弃缓存数据。当应用程序再次激活时,它将开始重新加载缓存。

谢谢。。有没有办法强制JVM收集所有对象进行清理?它确实收集了当时所有可用的对象。问题是某些对象无法立即收集。在收集对象之后需要做一些工作,而在GC期间无法执行这些工作,因此答案是;在当前的实现中,您想要的是不可能的。e、 g.在执行完全收集时,终结器无法运行,这反过来会产生一些垃圾,这在一般情况下是不可避免的。一般来说,您应该尽量减少终结器和引用的使用。如果这是一个问题,我会考虑修复代码,这样它就不会使用太多。简短的回答是,我不会担心几百MB的内存,我只会担心GB的内存。