记一次IDEA编译器调优
前言:
我们知道,IDEA是用Java写的,那么他肯定也存在虚拟机的调优的问题,那么今天我们就对它进行开刀。
下面是默认参数 位置在:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2\bin\idea64.exe.vmoptions
-Xms128m
-Xmx756m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-Djdk.http.auth.tunneling.disabledSchemes=""
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
我们从这里可以看到,堆最小分配了128M,最大分配了756M。
新生代用的是ParNew收集器,基于标记复制算法
老年代用的是CMS,基于标记清除算法。
优化前:
我们这里用到了两个神器。jvisualvm.exe和jconsole.exe。
我们先启动一下IDEA

新生代进行了56次gc,老年代进行了5次Full gc。这肯定不能忍受的嘛。
优化一:
1 -Xms1024m
2 -Xmx1024m
3 -Xmn350m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-Djdk.http.auth.tunneling.disabledSchemes=""
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow 14 -verbose:gc
15 -XX:+PrintGCDetails
16 -XX:+PrintGCDateStamps
17 -Xloggc:gcc.log
设置堆的最大最小都为1024M,不给动态扩容。并且设置新生代为350M,同时打出日志。

可以看到,只进行了7次新生代GC,3次老年代GC。
我很奇怪,为何老年代没有填满,并且还有好多空间,会发生三次FullGC呢?部分日志如下:
2018-08-20T22:35:57.399+0800: 3.963: [CMS-concurrent-preclean-start]
2018-08-20T22:35:57.399+0800: 3.965: [CMS-concurrent-preclean: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2018-08-20T22:35:57.399+0800: 3.965: [CMS-concurrent-abortable-preclean-start]
2018-08-20T22:35:59.457+0800: 6.018: [CMS-concurrent-abortable-preclean: 1.465/2.053 secs] [Times: user=6.16 sys=0.52, real=2.06 secs]
2018-08-20T22:35:59.458+0800: 6.019: [GC (CMS Final Remark) [YG occupancy: 167766 K (322560 K)]2018-08-20T22:35:59.458+0800: 6.019: [Rescan (parallel) , 0.0669837 secs]2018-08-20T22:35:59.525+0800: 6.086: [weak refs processing, 0.0000425 secs]2018-08-20T22:35:59.525+0800: 6.086: [class unloading, 0.0054995 secs]2018-08-20T22:35:59.530+0800: 6.091: [scrub symbol table, 0.0064731 secs]2018-08-20T22:35:59.537+0800: 6.098: [scrub string table, 0.0004637 secs][1 CMS-remark: 0K(690176K)] 167766K(1012736K), 0.0803359 secs] [Times: user=0.25 sys=0.00, real=0.08 secs]
2018-08-20T22:35:59.538+0800: 6.099: [CMS-concurrent-sweep-start]
2018-08-20T22:35:59.538+0800: 6.099: [CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2018-08-20T22:35:59.538+0800: 6.099: [CMS-concurrent-reset-start]
2018-08-20T22:35:59.540+0800: 6.101: [CMS-concurrent-reset: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2018-08-20T22:36:03.352+0800: 9.915: [GC (Allocation Failure) 2018-08-20T22:36:03.352+0800: 9.915: [ParNew: 310560K->29155K(322560K), 0.0792661 secs] 310560K->47946K(1012736K), 0.0793506 secs] [Times: user=0.25 sys=0.02, real=0.08 secs]
2018-08-20T22:36:07.438+0800: 14.013: [GC (CMS Initial Mark) [1 CMS-initial-mark: 18790K(690176K)] 255956K(1012736K), 0.0418642 secs] [Times: user=0.22 sys=0.00, real=0.06 secs]
2018-08-20T22:36:07.515+0800: 14.076: [CMS-concurrent-mark-start]
因为老年代是采用CMS,我们来分析下,什么情况下CMS会导致FullGC。
1:担保失败,即在并发清除,会有新生代担保进来,如果不足,则提前出发Full GC。
可通过 -XX:CMSInitiatingOccupancyFraction 来调整比例。
2:因为CMS是标记清除算法,势必会产生大量的碎片,导致Full GC
可通过调整老年代的大小来进行避免。
但经过上面两个分析,并进行了调整,发觉仍然会发生FullGC,并且老年代的空间还剩余特别的多,根本不存在空间不足,或者找不到连续空间的问题,那么为何还会进行Full GC呢。
优化二:
-Xms1024m
-Xmx1024m
-Xmn350m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-Djdk.http.auth.tunneling.disabledSchemes=""
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow -verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:gcc.log 19 -XX:MetaspaceSize=1024m
注意看最后一个参数-XX:MetaspaceSize=1024M
可以看到,此时一次FullGC都没有发生,新生代GC至发生了7次就已经完成了启动。
结论:
测试,我测试了好多遍,当然不会像博客这样简单的测试。差了好多资料,比了好多的数据。
优化前,大概启动进行50多次新生代GC,3-5次老年代GC。
优化后,进行7次左右新生代GC,0次老年代GC。
启动时间大概快了有10s。
分析一下为何,MetaSpaceGC 会引发一次CMS GC
JDK8: Metaspace
In JDK 8, classes metadata is now stored in the native heap
and this space is called Metaspace. There are some new flags added for
Metaspace in JDK 8:
-XX:MetaspaceSize= where is the initial amount of space(the initial
high-water-mark) allocated for class metadata (in bytes) that may induce a
garbage collection to unload classes. The amount is approximate. After the
high-water-mark is first reached, the next high-water-mark is managed by
the garbage collector
-XX:MaxMetaspaceSize= where is the maximum amount of space to be allocated for class
metadata (in bytes). This flag can be used to limit the amount of space
allocated for class metadata. This value is approximate. By default there
is no limit set.
-XX:MinMetaspaceFreeRatio= where is the minimum percentage of class metadata capacity
free after a GC to avoid an increase in the amount of space
(high-water-mark) allocated for class metadata that will induce a garbage collection.
-XX:MaxMetaspaceFreeRatio= where is the maximum percentage of class metadata capacity
free after a GC to avoid a reduction in the amount of space
(high-water-mark) allocated for class metadata that will induce a garbage collection.
By default class
metadata allocation is only limited by the amount of available native memory. We
can use the new option MaxMetaspaceSize to limit the amount of native memory
used for the class metadata. It is analogous(类似) to MaxPermSize. A garbage collection is induced to collect the dead classloaders
and classes when the class metadata usage reaches MetaspaceSize (12Mbytes on
the 32bit client VM and 16Mbytes on the 32bit server VM with larger sizes on
the 64bit VMs). Set MetaspaceSize to a higher value to delay the induced
garbage collections. After an induced garbage collection, the class metadata usage
needed to induce the next garbage collection may be increased.
JVM规范中运行时数据区域中的方法区,在HotSpot虚拟机中又被习惯称为永生代或者永生区,Permanet Generation中存放的为一些class的信息、常量、静态变量等数据,当系统中要加载的类、反射的类和调用的方法较多时,Permanet Generation可能会被占满,在未配置为采用CMS GC的情况下也会执行Full GC。如果经过Full GC仍然回收不了,那么JVM会抛出如下错误信息:java.lang.OutOfMemoryError: PermGen space 为避免Perm Gen占满造成Full GC现象,可采用的方法为增大Perm Gen空间或转为使用CMS GC。
即如果MetaSpace不足,也会触发Full GC(在64为机器上默认20.8M)。那么调大即可,延迟Full GC的时间。
参考资料:
https://blog.csdn.net/liubenlong007/article/details/78143285
http://tech.dianwoda.com/2018/01/10/jdk8-de-fullgc-zhi-metaspace/
记一次IDEA编译器调优的更多相关文章
- 记一次单机Nginx调优,效果立竿见影
一.物理环境 1.系统是Centos 8,系统配置 2核4G,8M带宽,一台很轻的应用服务器. 2.站点部署情况.但站点部署两个实例,占用两个端口,使用nginx 负载转发到这两个web站点. 二. ...
- [MYSQL] 记一次MySQL性能调优
最近在做数据迁移工作,已有一堆数据文件,要把这些数据文件写到MySQL 数据库里面去. MySQL数据库上架了一层服务接口,可以直接调用.博主写了一个迁移程序,放在服务器A上. *********** ...
- 记一次GreenPlum性能调优
在部署了的GreenPlum集群中进行数据查询时,发现数据量一旦大了,查询一跑就中断,提示某个segment中断了连接. ERROR 58M01 "Error on receive from ...
- 记一次idea性能调优
因自研的自动化测试工具包含压测功能,在自己本地代码开发完毕后进行测试,对目标接口进行1000次访问,发现idea在执行结束后变的异常卡顿,怀疑是idea工具或者程序代码存在问题,遂进行排查. ---- ...
- 记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?)
记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?) 前几天帮客户优化一个数据库,那个数据库的大小是6G 这麽小的数据库按道理不会有太大的性能问题的, ...
- Spark踩坑记:Spark Streaming+kafka应用及调优
前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark streaming从k ...
- 记Oracle中regexp_substr的一次调优(速度提高95.5%)
项目中需要做一个船舶代理费的功能,针对代理的船进行收费,那么该功能的第一步便是选择进行代理费用信息的录入,在进行船舶选择的时候,发现加载相关船舶信息十分的慢,其主要在sql语句的执行,因为测试的时候数 ...
- 记一次Web服务的性能调优
前言 一个项目在经历开发.测试.上线后,当时的用户规模还比较小,所以刚刚上线的项目一般会表现稳定.但是随着时间的推移,用户数量的增加,qps的增加等因素会造成项目慢慢表现出网页半天无响应的状况.在之前 ...
- 记一次sql server 性能调优,查询从20秒至2秒
一.需求 需求很简单,就是需要查询一个报表,只有1个表,数据量大约60万左右,但是中间有些逻辑. 先说明一下服务器配置情况:1核CPU.2GB内存.机械硬盘.Sqlserver 2008 R2.Win ...
随机推荐
- cpp 区块链模拟示例(六) 交易
交易(transaction)是比特币的核心所在,而区块链的唯一目的,也正是为了能够安全可靠地存储交易.在区块链中,交易一旦被创建,就没有任何人能够再去修改或是删除它.在今天的文章中,我们会实现交易的 ...
- Django Model模型的实战操作笔记
Model模型的实战操作笔记 1. 创建数据库和表 进入MySQL数据库创建数据库:mytest 进入数据库创建数据表:mytest_users CREATE TABLE `mytest_users` ...
- Oracle使用JDBC进行增删改查 表是否存在
Oracle使用JDBC进行增删改查 数据库和表 table USERS ( USERNAME VARCHAR2(20) not null, PASSWORD VARCHAR2(20) ) a ...
- 【转】机器学习在B2B的应用
原文地址:http://www.mbtmag.com/blog/2017/04/artificial-intelligence-making-it-work-industrial-companies? ...
- Python开发——5.函数
一.函数的定义 def test(x) "The Function definitions" x += return x def:定义函数的关键字 test:函数名 ():定义形参 ...
- Chapter6 胞内信号网络
一.一条从细胞表面到细胞核的通路 二.Ras蛋白处于复杂信号级联的中心位置 胞外信号→酪氨酸激酶受体→Shc→Grb→Sos→Ras 三.酪氨酸的磷酸化控制着许多胞内信号蛋白的定位与活动 Src蛋白的 ...
- 2018.09.22 上海大学技术分享 - An Introduction To Go Programming Language
老实说笔者学习 Go 的时间并不长,积淀也不深厚,这次因缘巧合,同组的同事以前是上海大学的开源社区推动者之一,同时我们也抱着部分宣传公司和技术分享的意图,更进一步的,也是对所学做一个总结,所以拟定了这 ...
- 如何减少SQL Server中的PREEMPTIVE_OS_WRITEFILEGATHER等待类型
在数据库大小分配期间,我正在等待类型PREEMPTIVE_OS_WRITEFILEGATHER.昨天,我将数据库大小配置为供应商建议的值.我们需要将数据库大小设置为700GB,保留150 GB的日志文 ...
- 2.html基础标签:无序+有序+自定义列表
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- linux下静态链接库和动态链接库
关于链接库的知识,网上太多资料了,但是并不代表我很熟悉.今天遇到了 一个问题,就是由于静态链接库和ubuntu系统不兼容导致的,虽然花了点时间才搞定 但是,其中暴露的问题也不少. 没有区分好静态链接库 ...
