JVM的命令行参数参考:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
HotSpot参数分类
标准: - 开头,所有的HotSpot都支持
非标准:-X 开头,特定版本HotSpot支持特定命令
不稳定:-XX 开头,下个版本可能取消
java -version
java -X
小程序:
public class T01_HelloGC {
public static void main(String[] args) {
System.out.println("Hello GC");
List list = new LinkedList();
for(;;) {
byte[] b = new byte[1024 * 1024];
list.add(b);
}
}
}
首先来看:java -XX:+PrintCommandLineFlags HelloGC
输出如下信息:
-XX:InitialHeapSize=257560512 -XX:MaxHeapSize=4120968192 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Connected to the target VM, address: '127.0.0.1:11937', transport: 'socket'
Hello GC
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Process finished with exit code 1
initialHeapSize起始堆大小,
maxHeapSize最大堆大小
注意:
内存有两种方式对虚拟机产生影响,第一种是内存泄漏(memory leak,废了的对象未回收空间)【不一定会产生内存溢出】,第二种是内存溢出(out of memory)
2、指令2:-Xmn10M -Xms40M -Xmx60M -XX:+PrintCommandLineFlags -XX:+PrintGC
一般我们-Xms和-Xmx堆最小和最大的大小设置成一样的,因为这样可以避免堆空间的弹性伸缩【当空间不够用了往大了弹,当空间大于我们使用的时候则往小弹】
-xmn:设置年轻代的大小
此外除了PrintGC以外还有PrintGCDetails,PrintGCTimeStamps【打印GC时间信息】,PrintGCCauses【打印GC产生的原因】
-XX:InitialHeapSize=41943040 -XX:MaxHeapSize=62914560 -XX:MaxNewSize=10485760//最大的年轻代大小 -XX:NewSize=10485760 -XX:+PrintCommandLineFlags -XX:+PrintGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Connected to the target VM, address: '127.0.0.1:12207', transport: 'socket'
Hello GC
GC:产生的YGC GC产生的原因:(Allocation Failure) 年轻代堆经过一次回收之后从多大变成多大:7782K->6176K(39936K)
[GC (Allocation Failure) 7782K->6176K(39936K), 0.0019873 secs]
[GC (Allocation Failure) 13666K->13360K(39936K), 0.0024044 secs]
[GC (Allocation Failure) 20761K->20432K(39936K), 0.0012763 secs]
[GC (Allocation Failure) 27754K->27664K(39936K), 0.0012923 secs]
//Old区域越来越大产生FullGC
[Full GC (Ergonomics) 27664K->27309K(54272K), 0.0076299 secs]
[GC (Allocation Failure) 34633K->34701K(53760K), 0.0021145 secs]
[GC (Allocation Failure) 42019K->41901K(50688K), 0.0013010 secs]
[Full GC (Ergonomics) 41901K->41646K(56832K), 0.0025557 secs]
[GC (Allocation Failure) 44794K->44846K(58368K), 0.0007178 secs]
[Full GC (Ergonomics) 44846K->44718K(58368K), 0.0020880 secs]
[GC (Allocation Failure) 47858K->47886K(58368K), 0.0007106 secs]
[Full GC (Ergonomics) 47886K->47790K(58368K), 0.0027907 secs]
[GC (Allocation Failure) 50925K->50958K(58368K), 0.0008849 secs]
[Full GC (Ergonomics) 50958K->50862K(58368K), 0.0028238 secs]
[Full GC (Ergonomics) 53994K->53934K(58368K), 0.0036053 secs]
[Full GC (Allocation Failure) 53934K->53918K(58368K), 0.0084963 secs]
//FullGC也清理不掉了则抛出OOM异常
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Process finished with exit code 1
再来看下面这个:-XX:+UseConcMarkSweepGC -XX:+PrintCommandLineFlags -XX:+PrintGC
会发现使用CMS垃圾回收器,回收对象会更频繁。
-XX:InitialHeapSize=257560512 -XX:MaxHeapSize=4120968192 -XX:MaxNewSize=1134141440 -XX:MaxTenuringThreshold=6 -XX:OldPLABSize=16 -XX:+PrintCommandLineFlags -XX:+PrintGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC
Connected to the target VM, address: '127.0.0.1:8895', transport: 'socket'
Hello GC
[GC (Allocation Failure) 66830K->62272K(243520K), 0.0180578 secs]
[GC (Allocation Failure) 129432K->127830K(243520K), 0.0212170 secs]
//初始标记
[GC (CMS Initial Mark) 128854K(243520K), 0.0001601 secs]
[GC (Allocation Failure) 194666K->194294K(263052K), 0.0213963 secs]
[GC (Allocation Failure) 261144K->260829K(329872K), 0.0209205 secs]
[GC (Allocation Failure) 327688K->327391K(395664K), 0.0267197 secs]
[GC (Allocation Failure) 394255K->393955K(462484K), 0.0658935 secs]
[GC (Allocation Failure) 460825K->460518K(529304K), 0.0351816 secs]
[GC (Allocation Failure) 527389K->527080K(596124K), 0.0232964 secs]
[GC (Allocation Failure) 593953K->593641K(661916K), 0.0210760 secs]
[GC (Allocation Failure) 660514K->660205K(728736K), 0.0188286 secs]
[GC (Allocation Failure) 727079K->726768K(795556K), 0.0205322 secs]
[GC (Allocation Failure) 793642K->793332K(862376K), 0.0234916 secs]
[GC (Allocation Failure) 860207K->859893K(928168K), 0.0210479 secs]
[GC (Allocation Failure) 926767K->926455K(994988K), 0.0200434 secs]
[GC (Allocation Failure) 993330K->993018K(1061808K), 0.0192223 secs]
[GC (Allocation Failure) 1059893K->1059582K(1128628K), 0.0200241 secs]
[GC (Allocation Failure) 1126457K->1126145K(1194420K), 0.0188897 secs]
[GC (Allocation Failure) 1193020K->1192706K(1261240K), 0.0190581 secs]
[GC (Allocation Failure) 1259580K->1259266K(1328060K), 0.0214457 secs]
[GC (Allocation Failure) 1326141K->1325831K(1394880K), 0.0243835 secs]
[GC (Allocation Failure) 1392705K->1392397K(1460672K), 0.0234791 secs]
[GC (Allocation Failure) 1459272K->1458958K(1527492K), 0.0245448 secs]
[GC (Allocation Failure) 1525832K->1525518K(1594312K), 0.0220823 secs]
[GC (Allocation Failure) 1592393K->1592081K(1661132K), 0.0207116 secs]
[GC (Allocation Failure) 1658956K->1658643K(1726924K), 0.0199758 secs]
[GC (Allocation Failure) 1725518K->1725208K(1793744K), 0.0197700 secs]
[GC (Allocation Failure) 1792083K->1791766K(1860564K), 0.0199459 secs]
[GC (Allocation Failure) 1858641K->1858329K(1927384K), 0.0192443 secs]
[GC (Allocation Failure) 1925204K->1924893K(1993176K), 0.0210410 secs]
[GC (Allocation Failure) 1991768K->1991456K(2059996K), 0.0196798 secs]
[GC (Allocation Failure) 2058331K->2058017K(2126816K), 0.0206533 secs]
[GC (Allocation Failure) 2124891K->2124581K(2193636K), 0.0213093 secs]
[GC (Allocation Failure) 2191456K->2191146K(2259428K), 0.0198410 secs]
[GC (Allocation Failure) 2258020K->2257706K(2326248K), 0.0195975 secs]
[GC (Allocation Failure) 2324581K->2324269K(2393068K), 0.0184608 secs]
[GC (Allocation Failure) 2391143K->2390831K(2459888K), 0.0220385 secs]
[GC (Allocation Failure) 2457706K->2457396K(2525680K), 0.0213528 secs]
[GC (Allocation Failure) 2524271K->2523956K(2592500K), 0.0220963 secs]
[GC (Allocation Failure) 2590831K->2590519K(2659320K), 0.0231794 secs]
[GC (Allocation Failure) 2657394K->2657081K(2726140K), 0.0248919 secs]
[GC (Allocation Failure) 2723956K->2723642K(2791932K), 0.0229990 secs]
[GC (Allocation Failure) 2790517K->2790209K(2858752K), 0.0217714 secs]
[GC (Allocation Failure) 2857083K->2856769K(2925572K), 0.0201481 secs]
[GC (Allocation Failure) 2923644K->2923332K(2992392K), 0.0206791 secs]
[GC (CMS Final Remark) 2924356K(2992392K), 0.0017975 secs]
[Full GC (Allocation Failure) 2989853K->2988836K(2994432K), 0.3383998 secs]
[Full GC (Allocation Failure) 2993570K->2992932K(2994432K), 0.0073082 secs]
[Full GC (Allocation Failure) 2992932K->2992916K(2994432K), 0.5134662 secs]
[GC (CMS Initial Mark) 2992916K(2994432K), 0.0001844 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Process finished with exit code 1
java -XX:+PrintFlagsFinal 最终参数值
java -XX:+PrintFlagsFinal | grep xxx 找到对应的参数
java -XX:+PrintFlagsFinal -version |grep GC
注意windows中用findstr:
-XX:+UseSerialGC = Serial New (DefNew) + Serial Old
-XX:+UseParNewGC = ParNew + SerialOld
-XX:+UseConcurrentMarkSweepGC = ParNew + CMS + Serial Old
-XX:+UseParallelGC = Parallel Scavenge + Parallel Old (1.8默认) 【PS + SerialOld】
-XX:+UseParallelOldGC = Parallel Scavenge + Parallel Old
-XX:+UseG1GC = G1
Linux中没找到默认GC的查看方法,而windows中会打印UseParallelGC
Linux下1.8版本默认的垃圾回收器到底是什么?
还是上面的那个程序:
设置JVM参数: -Xmn10M -Xms40M -Xmx60M -XX:+PrintCommandLineFlags -XX:+PrintGCDetails【设置输出GC的详细信息】
-XX:InitialHeapSize=41943040 -XX:MaxHeapSize=62914560 -XX:MaxNewSize=10485760 -XX:NewSize=10485760 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Connected to the target VM, address: '127.0.0.1:10121', transport: 'socket'
Hello GC
[GC (Allocation Failure) [PSYoungGen: 7782K->1016K(9216K)] 7782K->6176K(39936K), 0.0016007 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 【用户态占用时间,内核态占用时间,总占用多少时间】
[GC (Allocation Failure) [PSYoungGen: 8506K->1000K(9216K)] 13666K->13344K(39936K), 0.0015698 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 8401K->920K(9216K)] 20745K->20440K(39936K), 0.0022407 secs] [Times: user=0.13 sys=0.03, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 8242K->1016K(9216K)] 27762K->27704K(39936K), 0.0015286 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 1016K->0K(9216K)] [ParOldGen: 26688K->27309K(45056K)] 27704K->27309K(54272K), [Metaspace: 3326K->3326K(1056768K)], 0.0090290 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[GC (Allocation Failure) [PSYoungGen: 7324K->224K(8704K)] 34633K->34701K(53760K), 0.0016893 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 7541K->1248K(5632K)] 42019K->41869K(50688K), 0.0011368 secs] [Times: user=0.08 sys=0.06, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 1248K->0K(5632K)] [ParOldGen: 40621K->41646K(51200K)] 41869K->41646K(56832K), [Metaspace: 3326K->3326K(1056768K)], 0.0022957 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 3148K->2144K(7168K)] 44794K->44814K(58368K), 0.0008460 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 2144K->0K(7168K)] [ParOldGen: 42670K->44718K(51200K)] 44814K->44718K(58368K), [Metaspace: 3326K->3326K(1056768K)], 0.0026632 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 3140K->2176K(7168K)] 47858K->47918K(58368K), 0.0010636 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 2176K->0K(7168K)] [ParOldGen: 45742K->47790K(51200K)] 47918K->47790K(58368K), [Metaspace: 3326K->3326K(1056768K)], 0.0019098 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 3135K->2144K(7168K)] 50925K->50958K(58368K), 0.0007480 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 2144K->0K(7168K)] [ParOldGen: 48814K->50862K(51200K)] 50958K->50862K(58368K), [Metaspace: 3326K->3326K(1056768K)], 0.0020609 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 3131K->3072K(7168K)] [ParOldGen: 50862K->50862K(51200K)] 53994K->53934K(58368K), [Metaspace: 3326K->3326K(1056768K)], 0.0017782 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 3072K->3072K(7168K)] [ParOldGen: 50862K->50846K(51200K)] 53934K->53918K(58368K), [Metaspace: 3326K->3326K(1056768K)], 0.0071556 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
Heap
PSYoungGen total 7168K, used 3212K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 4096K, 78% used [0x00000000ff600000,0x00000000ff923038,0x00000000ffa00000)
from space 3072K, 0% used [0x00000000ffa00000,0x00000000ffa00000,0x00000000ffd00000)
to space 3072K, 0% used [0x00000000ffd00000,0x00000000ffd00000,0x0000000100000000)
ParOldGen total 51200K, used 50846K [0x00000000fc400000, 0x00000000ff600000, 0x00000000ff600000)
object space 51200K, 99% used [0x00000000fc400000,0x00000000ff5a7b30,0x00000000ff600000)
Metaspace used 3357K, capacity 4620K, committed 4864K, reserved 1056768K
class space used 360K, capacity 392K, committed 512K, reserved 1048576K
其后的堆信息:
年轻代,total=eden+1个survivor,因为复制算法,所以每次只会使用一个S0或者S1区域,还有一块区域空着留着复制
turnured generation是old区,说明了总的空间是多少
[0x00000000fec00000, 0x00000000ff2a0000, 0x00000000ff2a0000)
如上地址信息分别代表起始地址是在哪,然后使用空间的结束地址,以及整体空间的结束地址。
metaspace元数据区
class space 专门给class信息做存储的空间
1、吞吐量:用户代码时间/(用户代码执行时间+垃圾回收时间) ->吞吐量大说明程序越好【大量的计算用在程序计算上面,垃圾回收计算相对较少】
2、响应时间:STW越短,响应时间越好【将大量时间用在垃圾回收上面】响应时间目前是要求最多的
需要确定:
吞吐量优先还是响应时间优先?还是在满足一定的响应时间的情况下,要求多大的吞吐量。
如做科学计算及数据挖掘:吞吐量优先(一般采用PS+PO)
响应时间优先:网站,GUI界面,对外提供的API(1.8 G1或者PN+CMS)【G1(推荐内存够大的情况使用)CMS的吞吐量要比CMS低一些,大概在15%左右】
1、根据需求进行JVM规划和预调优
2、优化运行JVM运行环境
3、解决JVM运行过程中出现的各种问题(OOM【只是一部分】)
调优:从业务场景开始,没有业务场景的调优就是耍流氓
无监控【这里的监控指的是压力测试】,不调优
步骤:
1、熟悉业务场景(没有最好的垃圾回收器,只有最合适的垃圾回收期)
2、响应时间,停顿时间【CMS G1 ZGC】(需要给用户做响应)
3、吞吐量:用户代码时间/(用户代码执行时间+垃圾回收时间)【PS垃圾回收器】
【根据以上需求选定回收器的组合】
4、计算内存需求(内存大回收的慢一些,内存小回收的快一些)
5、选定CPU(越高越好)
6、设定日志参数:
-Xloggc:/opt/xxx/logs/xxx-xxx-gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCCause
-Xloggc:/opt/xxx/logs/xxx-xxx-gc-%t.log :日志文件,产生按照系统时间产生
-XX:+UseGCLogFileRotation: 循环产生五个日志文件
-XX:NumberOfGCLogFiles=5 :五个记录GC日志的文件
-XX:GCLogFileSize=20M:每个文件的大小为20M
能控制日志文件的总大小为100M
案例1:垂直电商【只卖某种产品】,最高每日百万订单,处理订单系统需要什么样的服务器配置?
很多服务器的配置都能支撑,可以找交易量最高峰的时间,假设每天五点到七点有720000订单在这两个
小时产生,平均一小时产生360000订单,每秒产生100个订单(找一小时内的高峰期,1000订单/秒)
在这个高峰时间架构要能撑住。【经验值:
一个订单产生需要多少内存?按照512k来计算, 1000个订单高峰则需要500M内存
如果要求响应时间在100ms的情况下,做压测来估算。
所以一般需要估算系统的内存以及CPU,不行则加CPU扩展内存,实在不行则上云
】
案例2:12306遭遇春节大规模抢票应该如何支撑?
号称并发量100W最高
CDN【在全国各个地方做缓存】->LVS->NGINX->业务系统->每台机器1W并发(单机10k问题),100台机器
12306用户下单可能会用到的模型为:用户下单->减库存和订单(redis kafka)同时异步进行->等待付款减库存
最后还会把压力压倒一台服务器。【可以做分布式本地库存+单独服务器做库存均衡】
大流量处理方式:分而治之
有一个50万PV的资料类网站(从磁盘提取文档到内存)原服务器32位,1.5G
的堆,用户反馈网站比较缓慢,因此公司决定升级,新的服务器为64位,16G
的堆内存,结果用户反馈卡顿十分严重,反而比以前效率更低了
为什么原网站慢?
很多用户浏览数据,很多数据load到内存,内存不足,频繁GC,STW长,响应时间变慢
为什么会更卡顿?
内存越大,FGC时间越长
如何优化?
PS -> PN + CMS 或者 G1
如果一个系统CPU经常100%,如何调优?
CPU100%那么一定有线程在占用系统资源
1、找出哪个进程CPU高(top)
2、该进程中的哪个线程CPU高(top -HP)
3、导出该线程的堆栈(jstack)
4、查找哪个方法(栈帧)消耗时间(jstack)
5、区分是工作线程占比高还是垃圾回收线程占比高
系统内存飙高,如何查找问题?
1、导出堆内存(jmap)
2、分析(jhat,jvisualvm mat jprofiler)