编程Java开发人员

Java中自动内存管理机制是如何工作的(垃圾收集器)?

用 Hintsage AI 助手通过面试

回答

在Java中,内存管理是通过自动垃圾回收(Garbage Collector,GC)来进行的。JVM会自动跟踪内存中的对象:如果一个对象没有更多的引用,它将变为不可达,并可以被删除。

GC由不同的阶段组成,例如标记(Mark)、清除(Sweep)和有时的压缩(Compact)。在标记阶段,能够从根(GC roots)访问到的对象被标记为活的。随后开始清除:未使用的对象被删除。有时会执行压缩——内存碎片整理。

GC有不同的类型:Serial、Parallel、CMS、G1。选择它们时应根据应用的负载类型。

代码示例 - 内存泄漏情况:
List<byte[]> dataList = new ArrayList<>(); while(true) { dataList.add(new byte[1024*1024]); // 对象保持可达 }

在这个例子中,对象永远不会变为不可达,GC不会删除它们,结果会出现OutOfMemoryError。

陷阱问题

如果一个对象没有更多的引用,什么时候可以保证调用它的终结器(finalize())?

回答: 根本无法保证调用finalize()方法!它可能从未被调用,或者有延迟。不能依赖finalize()来释放资源。

@Override protected void finalize() throws Throwable { // 可能不会被执行! }

因为不了解主题细节而导致的实际错误示例


故事

在一个大型电子商务系统中,开发人员希望通过finalize()方法自动清理临时文件,但由于这个方法被调用的频率极低,缓存被临时文件填满,导致磁盘不足和停机。


故事

在高负载的REST API中,偶然保存了对大型对象的内部引用缓存,妨碍了内存的释放。应用程序因OutOfMemoryError崩溃后,分析显示缓存方法存在错误。


故事

终结器被用于释放网络连接,以为这是“可靠的方法”。这导致连接在系统中悬挂不定的时间,造成阻塞和连接池耗尽。