性能问答>JDK的bug? 关于 新生代启用Parallel Scavenge 和 老生代启用Serial Old 组合>
10回复

JDK的bug? 关于 新生代启用Parallel Scavenge 和 老生代启用Serial Old 组合



根据这篇文章(https://openjdk.java.net/jeps/366)所说,应该是使用-XX:+UseParallelGC -XX:-UseParallelOldGC 可以启动这个组合。但是当我本地在jdk6、jdk8尝试的时候。打印的结果是
新生代:parallel Scavenge
老生代:Parallel Old 而不是 Serial Old。

如图所示:
1.png

如果是Serial Old应该显示(MarkSweepCompact才对吧?)如图所示:
2.png

GCInfo的代码如下所示:

    public static void printGCCollector() {
        List<GarbageCollectorMXBean> gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans();
        for (GarbageCollectorMXBean gcMxBean : gcMxBeans) {
            System.out.println(gcMxBean.getName());
            //System.out.println(gcMxBean.getObjectName()); jdk6没有这个API
        }
    }
4511 阅读
请先登录,再评论

这个主要是参考主要的GC算法,
-XX:+UseParallelGC说明用了PS算法,-XX:+UseSerialGC说明用了Serial GC算法

void MemoryService::set_universe_heap(CollectedHeap* heap) {
  CollectedHeap::Name kind = heap->kind();
  switch (kind) {
    case CollectedHeap::GenCollectedHeap : {
      add_gen_collected_heap_info(GenCollectedHeap::heap());
      break;
    }
#if INCLUDE_ALL_GCS
    case CollectedHeap::ParallelScavengeHeap : {
      add_parallel_scavenge_heap_info(ParallelScavengeHeap::heap());
      break;
    }
    case CollectedHeap::G1CollectedHeap : {
      add_g1_heap_info(G1CollectedHeap::heap());
      break;
    }
#endif // INCLUDE_ALL_GCS
    default: {
      guarantee(false, "Unrecognized kind of heap");
    }
  }
 ...
}

void MemoryService::add_gen_collected_heap_info(GenCollectedHeap* heap) {
  CollectorPolicy* policy = heap->collector_policy();

  assert(policy->is_two_generation_policy(), "Only support two generations");
  guarantee(heap->n_gens() == 2, "Only support two-generation heap");

  TwoGenerationCollectorPolicy* two_gen_policy = policy->as_two_generation_policy();
  if (two_gen_policy != NULL) {
    GenerationSpec** specs = two_gen_policy->generations();
    Generation::Name kind = specs[0]->name();
    switch (kind) {
      case Generation::DefNew:
        _minor_gc_manager = MemoryManager::get_copy_memory_manager();
        break;
#if INCLUDE_ALL_GCS
      case Generation::ParNew:
      case Generation::ASParNew:
        _minor_gc_manager = MemoryManager::get_parnew_memory_manager();
        break;
#endif // INCLUDE_ALL_GCS
      default:
        guarantee(false, "Unrecognized generation spec");
        break;
    }
    if (policy->is_mark_sweep_policy()) {
      _major_gc_manager = MemoryManager::get_msc_memory_manager();
#if INCLUDE_ALL_GCS
    } else if (policy->is_concurrent_mark_sweep_policy()) {
      _major_gc_manager = MemoryManager::get_cms_memory_manager();
#endif // INCLUDE_ALL_GCS
    } else {
      guarantee(false, "Unknown two-gen policy");
    }
  } else {
    guarantee(false, "Non two-gen policy");
  }
  _managers_list->append(_minor_gc_manager);
  _managers_list->append(_major_gc_manager);

  add_generation_memory_pool(heap->get_gen(minor), _major_gc_manager, _minor_gc_manager);
  add_generation_memory_pool(heap->get_gen(major), _major_gc_manager);
}

void MemoryService::add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap) {
  // Two managers to keep statistics about _minor_gc_manager and _major_gc_manager GC.
  _minor_gc_manager = MemoryManager::get_psScavenge_memory_manager();
  _major_gc_manager = MemoryManager::get_psMarkSweep_memory_manager();
  _managers_list->append(_minor_gc_manager);
  _managers_list->append(_major_gc_manager);

  add_psYoung_memory_pool(heap->young_gen(), _major_gc_manager, _minor_gc_manager);
  add_psOld_memory_pool(heap->old_gen(), _major_gc_manager);
}

2年前
回复 系统随机生成昵称:

正如上面的代码所示,PS下的输出,不会去区分UseParallelOldGC值不一样带来的不同效果,都是显示PS MarkSweep

2年前回复
回复 墨书:

嗯,MarkSweep可以有不同的实现逻辑,这个我可以理解。

还有个疑问请教下:

之前发的图 用的是 "-UseParallelOldGC"(减号)而不是 "+UseParallelOldGC"(加号),所以按照文章(https://openjdk.java.net/jeps/366) 老年代应该使用 Serial Old收集器。

我理解如果使用了Serial Old收集器输出应该是 "MarkSeepCompat"才对应,现在输出内容是PS MarkSweep 说明用的是 Parallel Old 收集器而非期望的 Serial Old收集器?不知道我这么理解对不对。

2年前回复
回复 系统随机生成昵称:

上面代码里其实已经说明了,PS是完全独立的一套实现,CollectedHeap::GenCollectedHeap和CollectedHeap::ParallelScavengeHeap,前者针对CMS和Serial GC,后者针对PS,虽然都是MarkSweep,但是可以有不同的实现逻辑

2年前回复
查看更多