java - > System.gc(); 这个调用是否会打开一个新线程?

ogz*_*ylz 5 java concurrency multithreading garbage-collection sequential

例如我这样的代码

...获取一些内存并丢失所有指向该内存的指针,以便System.gc(); 可以收集它.

调用System.gc();

做一些其他的任务;


这里做"做其他一些任务;" 和"System.gc();" 在paralel工作或做"做其他一些任务;" 等待"System.gc();" 被执行

谢谢

Chr*_*ail 7

您可能不应该使用System.gc().C/C++用户遇到java的一个常见误解是他们认为他们需要告诉虚拟机何时可以执行垃圾收集.实际情况是垃圾收集器经过高度优化,并且在最好的情况下自行执行此任务.通常不建议调用System.gc().

如果您确实调用System.gc(),它将"建议"系统执行垃圾收集.它通常不会实际执行集合.如果它在另一个线程中运行取决于实际的收集算法.默认设置将在运行时阻止所有内容.所以它可能在不同的线程中运行,但它会阻止你当前的执行.


Yis*_*hai 6

这里的确切行为完全取决于JVM实现.在规范中(这是正确的JVM实现需要为您提供),它可以并行发生,它可以在代码执行之前发生,或者根本不会发生.

实际上,我对JVM的观察结果是我在一个单独的线程中立即运行.但是,在某些情况下,多个调用会产生多个线程,有时它会在一个线程上对请求进行排队.启动的垃圾收集始终是"停止世界"类型(即它非常完整,缓慢或暂停应用程序).

但是,鉴于您对@Chris Dail的评论,您的基本问题不是System.gc()调用的行为.调用System.gc()可以有一些用途.它可以用于清晰的内存,因此您可以了解应用程序的占用空间当前有多大.它还可以用作一种策略,以确保更早发生世界各地的垃圾收集,以便在更短的时间内"停止世界",因为需要清除更少的内存.(我应该注意到,随着JVM变得越来越复杂,这种事情越来越不必要了,实际上会产生适得其反的效果).

然而,它没有做的是以任何方式解决OutOfMemoryError.JVM在它尽可能地收集垃圾之前不会给你一个OutOfMemoryError.调用System.gc不会改变它.如果你有一个OutOfMemoryError,很可能是因为你以你真正不需要的方式持有对象的引用,但是这会阻止那些对象的内存被回收.