1. 既有 GC 机制,为什么还会有内存泄露的情况
理论上 Java 因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是 Java 被广泛使用于服务器端编程的一个重要原因)。然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被 GC 回收,因此也会导致内存泄露的发生。
例如 hibernate 的 Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)或清空(flush)一级缓存就可能导致内存泄露。
2. 对于 Java 的 GC 哪些内存需要回收
- 内存运行时 JVM 会有一个运行时数据区来管理内存。主要包括 5 大部分:程序计数器(Program CounterRegister)、虚拟机栈(VM Stack)、本地方法栈(Native Method Stack)、方法区(Method Area)、堆(Heap).
- 而其中程序计数器、虚拟机栈、本地方法栈是每个线程私有的内存空间,随线程生亡。如栈中每个栈帧中分配多少内存基本上在类结构确定是哪个时就已知了,因此这 3 个区域的内存分配和回收都是确定的,无需考虑内存回收的问题。
- 但方法区和堆就不同了,一个接口的多个实现类需要的内存可能不一样,只有在程序运行期才知道会创建哪些对象,这部分内存的分配和回收都是动态的,GC 主要关注的是这部分内存。
- 总而言之,GC 主要进行回收的内存是 JVM 中的方法区和堆;