为什么方法调用System.gc()
不能保证垃圾收集器算法在那一刻运行?为什么在调用它时它肯定不能回收所有未使用的对象的内存?
4 回答
- 强制对象销毁是错误编码的标志,因此 Java 可能希望避免开发人员沉迷于它。
- 如果 Java 为您提供强制对象销毁的自由,那么不当使用它可能会对应用程序性能产生不利影响。
- 这个限制允许你(强迫你)把更多的注意力放在业务逻辑上而不是内存管理上
- JVM 是决定何时需要内存管理以及如何进行管理的最佳人选。
- 您可以(应该)信任 JVM 并让它以比我们更好的方式处理事情。
- 还是真的要强制对象销毁?如果是,为什么?
为了保证程序在 JVM 内顺利运行,JVM 自己管理垃圾回收。垃圾收集已经变得相当复杂。当您要求系统运行 GC 时,您期望使用哪种算法?一个“完整的GC”?还有多个堆;你关心的垃圾是哪一个?你不知道,这个方法没有说明。
假设调用System.gc()
总是触发完整的 GC。错误的程序很容易使 JVM 性能陷入停顿。出于防御目的,JVM 希望限制它响应此类调用的频率。
如果您在非嵌入式系统(例如服务器或台式计算机)上的 JVM 中运行,则除了监控它和有效地编码之外,您没有理由关心内存管理的任何方面。
有几个指标可用于评估垃圾收集器的性能,其中一些是:
- 吞吐量——在很长一段时间内没有花在垃圾收集上的总时间的百分比。
- 垃圾收集开销——吞吐量的倒数,即垃圾收集所花费的总时间的百分比。
- 暂停时间——垃圾收集发生时应用程序执行停止的时间长度。
- 收集频率——收集发生的频率,相对于应用程序执行。
- 占用空间——大小的度量,例如堆大小。
- 即时性——从对象变成垃圾到内存可用之间的时间。
现在如果 JVM 监听System.gc()
like good pet 并保证每次System.gc()
调用都执行操作,想象一下如果在程序中多次调用应用程序的性能会是什么。!!??
- 吞吐量将下降
- 垃圾收集开销会增加。
- 应用程序将暂停很多次,因为它正忙于回忆内存。
- 如果 Footprint 很大,垃圾收集器必须扫描所有内存区域以恢复内存,无论是否有适合垃圾收集的对象。
因此,在查看了这些要点之后,我想它为 JVM 提供了足够的理由不响应System.gc
应用程序的选择,而是响应它自己的算法。Garbage Collection 肯定会回收所有未使用对象的内存,但它的调用完全取决于 JVM 自己的算法,而不是用户的选择。
资料来源:Java HotSpot™ 虚拟机中的内存管理 - Sun Microsystems
每当调用它时,它肯定不能回收所有未使用的对象的内存
你的这个假设是错误的。在大多数情况下,垃圾收集器可以在任何时间点回收所有未使用的对象。但是,如果标准 Java 库提供了一种方法来保证这一点,它将给 GC 子系统带来完全不合理的负担,以提供大部分时间无用甚至可能具有破坏性的服务。