parallel old收集器是jvm中用于老年代(old generation)的并行垃圾回收器,它采用多线程并发执行垃圾回收任务,旨在最大化吞吐量。该收集器通常与parallel scavenge新生代收集器配合使用,构成parallel scavenge + parallel old组合,这是java 7及以后版本默认的吞吐量优先配置。启用方式是通过命令行参数`-xx:+useparalleloldgc`,它会利用所有可用的cpu核心来扫描和压缩堆内存中的存活对象,从而减少stw(stop-the-world)时间对吞吐量的影响。

Parallel Old如何与其他收集器组合工作
Parallel Old主要作为老年代回收策略,与新生代收集器搭配使用。最常见的组合是与Parallel Scavenge新生代收集器配对,形成吞吐量优先的架构。在这种模式下,新生代负责快速回收短期存活的对象,而老年代则通过Parallel Old处理长期存活的对象。这种分工确保了系统在高负载下能保持较高的指令执行效率。另一种常见组合是与CMS收集器搭配,即ParNew + CMS,但Parallel Old本身不直接参与CMS的并发标记阶段,而是作为CMS失败后的后备方案或独立使用。

public class ParallelOldDemo {
public static void main(String[] args) {
// 模拟大量数据填充老年代
byte[] data = new byte[10 * 1024 * 1024]; // 10MB
System.out.println("Allocated 10MB in heap");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 触发GC
System.gc();
System.out.println("GC triggered");
}
}
运行上述代码时,若JVM参数设置为`-XX:+UseParallelOldGC -Xmx128m -Xms128m`,JVM将使用Parallel Old进行老年代回收。输出显示分配了10MB内存并触发GC,实际行为中Parallel Old会启动多个线程清理不可达对象。预期结果是控制台打印“Allocated 10MB in heap”和“GC triggered”,且无异常抛出。验证时需观察GC日志,确认出现`[Parallel Old]`字样,表明老年代回收由Parallel Old执行。此程序展示了基本用法,但未涉及复杂场景,仅用于确认收集器激活状态。
Parallel Old在Full GC中的表现
当堆空间不足或显式调用System.gc()时,Parallel Old会参与Full GC过程。Full GC会暂停所有应用线程,执行完整的垃圾回收,包括年轻代、老年代和元空间。Parallel Old在此过程中采用标记-清除-压缩算法,确保堆内存紧凑化,避免碎片化问题。相比CMS,Parallel Old的STW时间可能更长,但其吞吐量优势明显,适合批处理或后台服务。在实际应用中,需监控GC频率和停顿时间,以调整堆大小和线程数。

public class FullGCDemo {
public static void main(String[] args) {
List<byte> list = new ArrayList();
for (int i = 0; i
<p>运行此代码时,若JVM参数为`-XX:+UseParallelOldGC -Xmx128m -Xms128m`,JVM将在list.clear()后触发Full GC。Parallel Old会回收不再引用的字节数组,释放内存。预期结果是控制台打印“Added 100MB to list”和“Cleared list and triggered GC”,且无OutOfMemoryError。验证时需检查GC日志,确认`[Full GC [Parallel Old]`条目,表明老年代被完整回收。此示例强调了Parallel Old在Full GC中的角色,适用于需要高吞吐量的场景。注意,频繁Full GC可能导致性能下降,应优化对象生命周期或增加堆大小。</p>
<h2>Parallel Old如何处理大对象分配</h2>
<p>Parallel Old在处理大对象时,会优先尝试在老年代直接分配,若空间不足则触发Minor GC。大对象指超过阈值(默认由-XX:PretenureSizeThreshold控制)的对象,如大型数组或字符串。Parallel Old通过并行扫描识别这些对象,并在压缩阶段移动它们以减少碎片。若大对象导致老年代溢出,系统将执行Full GC,此时Parallel Old会暂停所有线程,执行完整回收。为避免频繁Full GC,建议合理设置堆大小和大对象阈值,或使用G1等更灵活的收集器。</p></byte>
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











