java垃圾回收那点事(五)ParallelGCThreads参数

10071人阅读 评论(0) 收藏 举报
分类:

为了提高垃圾回收的性能,java在parallel回收的时候可以设置同时并行处理的线程数也就是ParallelGCThreads,如果你没有设置该参数,该参数jvm会默认设置成online的cpu的核数但并不包括被shutdown的cpu的核数。

Linux 下获取online的cpu的核数

int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);

前面曾经提到过GC的主要过程是由VMThread线程执行,在执行parallel的时候,VMThread线程实际上是在等待线程执行结果的,这也就是为什么并没有设置ParallelGCThreads= online cpu core-1


Parallel gc 和CMS里的young区都可以设置ParallelGCThreads参数,下面主要讲的是Parallel GC

1. Parallel Threads 初始化

Parallel Threads本质是由gcTaskManager管理的gcTaskThread, 在parallelScavenge.cpp 中的initialize() 方法中通过GCTaskManager::create(ParallelGCThreads);初始化gcTaskThread的,也就是当jvm启动的时候thread 就已经创建并且运行。

参数:BindGCTaskThreadsToCPUs

 jvm在linux中并没有对gcTaskThread线程绑定到固定的cpu上,但在solaris上却支持了,请参考函数os::distribute_processes 和 os::bind_to_processor


2. GCTaskQueue

这是一个存放的元素是GCTask的链表结构,指针_insert_end指向最后一个元素,指针_remove_end指向第一个元素

GCTask本身也是一个链表结构,指针_newer指向后面的元素,_older指向前面一个元素,可以参考下面的图


当增加一个GCTask C的时候,会从Queue中取出_insert_end的GCTask B,设置B _newer 为C, 设置C older_为B,设置_insert_end为C

当取一个GCTask的时候,从Queue取出_remove_end的GCTask B, 设置_remove_end为C,设置C的old为null, 设置 B的new为nul


参数 UseGCTaskAffinity

通过设置_affinity 属性用于表示该task的是由哪个线程执行,当GCTaskThread运行的时候会取出该线程的所对应的task

做法使用轮询从queue的第一个开始顺序查找,一直找到然后移除。


3. GCTaskThread 运行

GCTaskThread不停轮询GCTaskQueue,当Queue里面没有数据的时候,线程会wait等待,直到有数据插入notify线程,由于Queue的操作并不是线程安全的,需要在增加和删除的时候申请互斥锁MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);


VMthread 线程在Parallel GC 时候将任务添加到queue中,然后等待结果。



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:447439次
    • 积分:5049
    • 等级:
    • 排名:第6113名
    • 原创:97篇
    • 转载:3篇
    • 译文:0篇
    • 评论:72条
    最新评论