优化eclipse,浅谈CMS

启动时间插件

为了检测启动时间,需要写一个插件来实现。
这边我写好了一个,基于jdk1.8 +eclipse Neon.3 Release (4.6.3)编写的插件下载:

链接:https://pan.baidu.com/s/1W4HEJeN6WIR4-TMG4vm-Wg 密码:qfyw

下载完,将这个jar包拷贝到eclipse 的plugins 目录下。

如果读者不是1.8,或者eclipse版本不一致而不能使用,烦劳告知,然后可以参考:

Eclipse简单插件开发-启动时间提示

eclipse的插件开发-启动时间

这两篇文章自己开发一个时间插件。

优化前

优化前:

image.png

这里就是39m ,无法忍受。

eclipse 安装目录下 eclipse.ini中启动参数配置如下:

-startup
plugins/org.eclipse.equinox.launcher_1.3.201.v20161025-1711.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.401.v20161122-1740
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
-showsplash
org.eclipse.platform
--launcher.defaultAction
openFile
--launcher.appendVmargs
-vmargs
-Dosgi.requiredJavaVersion=1.8
-XX:+UseG1GC
-XX:+UseStringDeduplication
-Dosgi.requiredJavaVersion=1.8
-Xms256m
-Xmx1024m

-vm 
D:/surroundings/jdk1.8.0_131/bin/javaw.exe
-startup
...
  • eclipse 启动时间:30144ms
    再启动一遍,时间是30s左右了,多次启动,在28s 左右。
image.png
image.png

堆这一块暂时还好,没有扩展,那么先看看Metaspace 这一块。

Metaspace 是什么呢?

JDK8以前,JVM 的数据区是这样的:

image.png
  • 红框框外面的方法区和Java堆是共享的
  • 方法区有个名字叫non-heap

对于习惯在HotSpot 虚拟机上开发、部署程序的开发者来说,很多人都更愿意把方法区称为”永久代“,本质上两者不等价,仅仅是因为HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,或者说使用永久代来实现方法区,这样HotSpot 的垃圾收集器可以像管理Java堆一样管理这部分内存,能够省去专门为方法区编写内存管理代码的工作。
...
这样更容易遇到内存溢出问题(永久代有-XX:MaxPermSize 的上限,J9和JRockit 只要没有触碰到进程可用内存的上限,例如32位系统中的4GB,就不会出现问题)而且有极少数方法(例如String.intent())会因为这个原因导致不同虚拟机下有不同的表现。
...
--------深入理解Java虚拟机(第二版)

回顾一下方法区

  • 各个线程共享
  • 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
  • 这个区域的内存回收主要是针对常量池的回收和对类型的卸载。而字符串常量池在JDK1.7就被移出了。
image.png

从JDK8开始,永久代(PermGen)的概念被废弃掉了,取而代之的是一个称为Metaspace的存储空间。Metaspace使用的是本地内存,而不是堆内存,也就是说在默认情况下Metaspace的大小只与本地内存大小有关。可以通过以下的几个参数对Metaspace进行控制:

  • -XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
  • -XX:MaxMetaspaceSize,最大空间,默认是没有限制的。

除了上面两个指定大小的选项以外,还有两个与 GC 相关的属性:

  • -XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集
  • -XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集

再来分析Metaspace 报告

然后回过头在分析我们的启动图,说明启动eclipse时加载大量的类,Metaspace初始内存太小,eclipse加载了多少类呢?至少插所有插件都要吧,还有其他基本功能支持,这里也说明插件越多是会越卡的。

image.png

这边发现Metaspace 最后稳定在150M 下面,那干脆初始化给他这么多好了。

好像没啥卵用,那就限制一下最大值吧,毕竟没限制不是很好。按照我的理解,他应该是有动态扩展的,可是没调好,路过的大牛还请指教一把。
-XX:MaxMetaspaceSize=500m

取消字节码验证过程

Eclipse的编译代码一般来说是可靠的,所以就不需要在加载的时候在进行字节码验证了。
果然带来了巨大的性能提升。


image.png

看看GC

image.png

Minoc GC 也就0.9s,Full GC 还直接没有,那就无可挑剔了。

要不屏蔽一下System.gc()这个,万一eclipse调用了就无视他。

-XX:DisableExplicitGC

好像很久以前优化过,现在觉得survivour 给太多了,并且拒绝堆扩充

-Xms512m
-Xmx512m
-Xmn128m
image.png
-XX:+UseG1GC

这边默认我是配置了G1来做垃圾收集,换成ParNew+CMS看看:

-XX:+UserConcMarkSweepGC
-XX:+ParNewGC
image.png
image.png

这边补充一下怎么看图

image.png

GC Time :29 collection,774.130ms Last Cause:Allocation Failure

  • 总GC时间:29次收集,774ms,最后一次收集原因:Allocation Failure。Eden区不够放,所以要触发一次Minor GC
  • Eden Space (102.500M, 102,500M):71.963M, 27 collections,698.397ms

Eden 区最大可分配102.500M,已分配102.500M,已用71.963M

  • 设置打印日志:

    • -XX:+PrintGCTimeStamps 打印GC停顿时间
    • -XX:+PrintGCDetails 打印GC详细信息
    • -verbose:gc 打印GC信息,被PrintGCDetails 包括了
    • -Xloggc:gc.log 指定文件

这边设置一下CMS在老年代被使用多少就触发一次垃圾收集:85%

  • -XX:CMSInitiatingOccupancyFraction=85

看GC日志去

打开GC日志:

-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-Xloggc:gc.log


...

26.052: [GC (CMS Initial Mark) [1 CMS-initial-mark: 201921K(393216K)] 215802K(511232K), 0.0057104 secs] [Times: user=0.06 sys=0.00, real=0.01 secs] 
26.058: [CMS-concurrent-mark-start]
26.267: [CMS-concurrent-mark: 0.209/0.209 secs] [Times: user=0.73 sys=0.08, real=0.21 secs] 
26.267: [CMS-concurrent-preclean-start]
26.270: [CMS-concurrent-preclean: 0.003/0.003 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
26.270: [CMS-concurrent-abortable-preclean-start]
27.552: [GC (Allocation Failure) 27.552: [ParNew: 118015K->13056K(118016K), 0.0507721 secs] 319937K->231818K(511232K), 0.0508436 secs] [Times: user=0.16 sys=0.00, real=0.05 secs] 
28.266: [CMS-concurrent-abortable-preclean: 1.573/1.995 secs] [Times: user=6.65 sys=0.72, real=1.99 secs] 
28.266: [GC (CMS Final Remark) [YG occupancy: 67278 K (118016 K)]28.266: [Rescan (parallel) , 0.0137578 secs]28.280: [weak refs processing, 0.0015506 secs]28.282: [class unloading, 0.0189432 secs]28.301: [scrub symbol table, 0.0233572 secs]28.324: [scrub string table, 0.0026839 secs][1 CMS-remark: 218762K(393216K)] 286040K(511232K), 0.0630204 secs] [Times: user=0.11 sys=0.00, real=0.06 secs] 
28.329: [CMS-concurrent-sweep-start]
28.372: [CMS-concurrent-sweep: 0.043/0.043 secs] [Times: user=0.08 sys=0.01, real=0.04 secs] 
28.372: [CMS-concurrent-reset-start]
28.373: [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
  1. CMS Initial Mark :初始标记,找到GC Roots,Stop the wrold,耗时0.0057104 s Times[]是详细时间。
26.052: [GC (CMS Initial Mark) [1 CMS-initial-mark: 201921K(393216K)] 215802K(511232K), 0.0057104 secs] [Times: user=0.06 sys=0.00, real=0.01 secs] 
  1. CMS-concurrent-mark-start: 开始并发标记,并发标记就是根据GC Roots做可达性分析
26.058: [CMS-concurrent-mark-start]
26.267: [CMS-concurrent-mark: 0.209/0.209 secs] [Times: user=0.73 sys=0.08, real=0.21 secs] 
CMS-concurrent-mark: 并发标记结束,耗0.209个cpu时间,0.209个墙钟时间
  1. CMS-concurrent-preclean-start: 并发预清理,这边也就是重新标记,并发标记阶段,用户线程对引用的修改会记录在日志中,而在并发预清理阶段合并到GC Roots,也就是把并发标记阶段用户对引用的修改也考虑进来。
26.267: [CMS-concurrent-preclean-start]
26.270: [CMS-concurrent-preclean: 0.003/0.003 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
  1. CMS-concurrent-abortable-preclean-star:

据说:

加入此阶段的目的是使cms gc更加可控一些,作用也是执行一些预清理,以减少Rescan阶段造成应用暂停的时间

不是很懂,求指教...

26.270: [CMS-concurrent-abortable-preclean-start]
...
28.266: [CMS-concurrent-abortable-preclean: 1.573/1.995 secs] [Times: user=6.65 sys=0.72, real=1.99 secs] 

中间插了一个Allocation Failure,PreNew 是新生代的事情,跳过

  1. CMS-concurrent-sweep-start: 同步整理开始
28.329: [CMS-concurrent-sweep-start]
28.372: [CMS-concurrent-sweep: 0.043/0.043 secs] [Times: user=0.08 sys=0.01, real=0.04 secs] 
  1. CMS-concurrent-reset-start 重置

    并发重置线程

28.372: [CMS-concurrent-reset-start]
28.373: [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

在本阶段,重新初始化CMS内部数据结构,以备下一轮 GC 使用。本阶段费时0.000秒

回顾一下CMS

image.png
  • 以最短回收时间为目标。致力于响应速度,适合交互
  • CMS:Concurrent Mark Sweep:并发标记清除,会产生碎片
  • 老年代
  • CPU 敏感
  • 无法处理浮动垃圾,重新标记阶段会考虑并发标记阶段用户线程产生的垃圾,但是之后产生的来及就无能为力。
    • 用户线程并发导致:
      • 产生浮动垃圾
      • 需要内存空间,所以要设置 CMSInitiatingOccupancyFraction ,不能等老年代满了再触发回收
    • 备用预案:Serial Old

总结

有没有觉得后面文笔都走理论了,好,回到调优eclipse,目前就调到:

image.png

比较弱,也请大家支招继续优化。

  • 由于能力有限,纰漏难免,万望各位朋友指正。
  • 本文参考了很多大牛的文章,大家在阅读的同时,可以看一下这些文章。

了解 CMS 垃圾回收日志
Java 1.8中的Metaspace总结
jdk8 Metaspace 调优
Java8内存模型—永久代(PermGen)和元空间(Metaspace)
JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,454评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,553评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,921评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,648评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,770评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,950评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,090评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,817评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,275评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,592评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,724评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,409评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,052评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,815评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,043评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,503评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,627评论 2 350

推荐阅读更多精彩内容