jav*_*ped 0 java garbage-collection
这不是重复,因为提到重复的线程只告诉你为什么不使用System.gc(),而我知道,这不是我的问题.
使用System.gc()或Runtime.getRuntime().gc()并不总是执行垃圾收集,它只是请求它,它甚至可以被JVM忽略.
这背后有原因吗?它是"随机的"吗?由于我不认为随机甚至存在于编程中,我很好奇它为什么有时不收集它,有时也会在不同的时间收集它.
是.有一个很好的理由.
首先,您需要了解有关垃圾收集的一些事实:
所以对你的问题:
使用System.gc()或Runtime.getRuntime().gc()并不总是执行垃圾收集,它只是请求它,它甚至可以被JVM忽略.这背后有原因吗?
是.它主要是为了防止天真的程序员gc()在错误的时间调用可能造成的灾难性行为影响.
它是"随机的"吗?
不.它与随机性无关.
实际上,典型的JVM有一个命令行开关,用于确定是否gc()忽略调用.这允许用户/部署者/集成商/任何人减轻程序员做出的糟糕选择.
但请注意,它无法从Java代码中重写.这会破坏使其成为命令行开关的目的.
我很好奇为什么它有时不会收集它,有时也会在不同的时间收集它.
JVM的正常行为是在最有效的情况下尝试运行垃圾收集器.JVM可以优化两种方式:
它可以优化以最大化收集器的吞吐量; 即最小化在收集上花费的CPU时间
它可以优化以最小化GC暂停的长度; 即JVM在收集期间必须冻结所有应用程序线程的时间.
这很复杂.从外部观察者(谁/无法访问堆统计数据等)的角度来看,可能很难理解为什么GC在给定时间点运行.但肯定不是随意的.
1 - GC算法的一个反直觉属性是收集成本(在大多数情况下)由跟踪非垃圾对象和在内存中移动以合并释放空间的成本支配.因此,如果在没有太多垃圾收集的情况下调用GC,您将最终跟踪/移动大量非垃圾,实际上没什么好处.相比之下,JVM可以更好地了解何时是收集的好时机.首先,它知道在任何时间点每个池中剩余多少空间.
除了反直觉之外,随着堆变大,这种行为也会变得更糟.因此,程序员可以编写gc()以错误方式使用的代码,而不会注意到存在性能问题.当应用程序以生产工作负载/问题大小运行时,性能只会成为问题.将此与使用堆缓存内容和/或内存泄漏的效果相结合.....