Java学习--JVM(2)
JVM提供垃圾回收机制,其也是JVM的核心机制,其主要是实现自动回收不再被引用的对象所占用的内存;对内存进行整理,防止内存碎片化;以及对内存分配配进行管理。
JVM 通过两种主要算法判断对象是否可回收:
引用计数算法:为每个对象维护一个引用计数器,每被一个对象调用,则计数加1,当计数为 0 时,也就是没有被对象调用的时候,即表示该对象可被回收。然而,这个算法无法解决循环引用问题,即a调用b,b调用a的情况,因此已被主流 JVM 弃用。
可达性分析算法:从 GCRoots 开始,通过引用链判断对象是否可达。不可达的对象被视为垃圾。GC Roots 包括虚拟机栈中的局部变量、类的静态字段、本地方法栈中的 JNI 引用等,企业是目前主流JVM所使用的算法。
JVM的垃圾回收机制根据内存区域的不同采用不同的回收策略:
堆内存回收:主要针对新生代和老年代采用分代收集算法。新生代使用复制算法,将内存分为Eden区和两个Survivor区,对象首先在Eden区分配,经历Minor GC后存活对象被复制到Survivor区。老年代采用标记-清除或标记-整理算法处理长期存活的对象。
方法区回收:主要回收废弃的常量和不再使用的类。由于回收条件苛刻且收益较低,通常不频繁执行。需要满足类的所有实例已被回收、类加载器已被回收、类的Class对象没有被引用三个条件才会被回收。
JVM提供多种垃圾收集器以适应不同场景:
串行收集器:单线程执行垃圾回收,适用于客户端模式和小内存应用,回收时会产生停顿。
并行收集器:多线程并行回收,适合吞吐量优先的应用场景,能有效利用多核CPU资源。
并发标记清除收集器:在应用线程运行同时进行大部分回收工作,显著减少停顿时间,适合响应时间敏感的应用。
JVM还提供内存分配和调优相关机制:
对象优先在Eden区分配,大对象直接进入老年代,长期存活的对象通过年龄阈值晋升到老年代。
通过调节新生代与老年代比例、设置停顿时间目标、调整垃圾回收线程数等参数可优化GC性能。
使用内存逃逸分析和栈上分配等技术减少堆内存压力,某些情况下对象可直接在栈上分配和回收。