1.元空间(metaspace)
1.1.当JVM加载类时,它必须记录这些类的某些元数据,这些数据占据的一个单独的堆空间,即元空间
1.2.元空间里的信息只在编译器和JVM运行时使用,它所保存的数据被称为类元数据(class metadata)
1.2.1.对于终端用户,元空间是不透明的
1.2.2.元空间并不保存类的实例或者反射对象
1.3.通过永久代(permgen)的实现来处理的
1.4.元空间的大小与它所使用的类的数量成正比
1.5.-XX:MetaspaceSize=N
1.5.1.初始大小
1.6.-XX:MaxMetaspaceSize=N
1.6.1.最大值
1.7.元空间大小的默认值
1.7.2.优化永久代在过去相当普遍,而现在优化元空间相当罕见,因为空间丰富
1.8.调整元空间的大小会导致Full GC,这是代价高昂的操作
1.9.如果在应用程序的启动过程中(它在加载类)有大量的Full GC,往往是因为永久代或元空间正在调整大小
1.10.定义并丢弃大量类的应用程序,在元空间被填满且旧的类被删除时,偶尔会发生Full GC。这在开发环境中很常见
1.11.服务器通常将元空间的初始大小设定为128 MB、192 MB或更大
1.12.增加元空间的初始值是改善启动过程的好主意
1.13.元空间的初始大小可以基于所有类都加载之后的使用量来设置,这会稍微加快启动速度
1.14.限制元空间大小的一个原因是防止类加载器泄漏
1.15.jmap可以和-clstats一起使用,以输出有关类加载器的信息
2.控制并行
2.1.除了Serial垃圾回收器,所有的GC算法都使用了多线程
2.2.-XX:ParallelGCThreads=N
2.2.1.设置线程的数量
2.2.2.使用-XX:+UseParallelGC时新生代的回收
2.2.3.使用-XX:+UseParallelGC时老年代的回收
2.2.4.使用-XX:+UseG1GC时新生代的回收
2.2.5.G1 GC的STW停顿阶段(不包括Full GC)
2.3.默认情况下,JVM将在机器的每个CPU上都运行一个线程,最多同时运行8个,达到这个阈值后,JVM每1.6个CPU会再增加一个新线程
2.4.超过8个CPU的机器上,线程总数计算
2.4.1.ParallelGCThreads = 8 + ((N - 8) * 5 / 8)
2.4.2.N表示CPU的数量
2.5.如果机器上运行的JVM不止一个,那么最好限制所有JVM的GC线程总数
2.6.当多个JVM运行在同一台机器上时,基于公式计算出的线程数量会过高,实际情况中必须减少使用的线程数量
3.GC工具
3.1.GC日志是诊断GC问题所需的关键数据,应该定期收集它们(即使是在生产服务器上)
3.2.在JDK 8中开启GC日志
3.2.1.设定-verbose:gc和-XX:+PrintGC中的任意一个,都会创建简单的GC 日志
3.2.1.1.这两个标志是彼此的别名
3.2.1.2.日志默认情况下是关闭的
3.2.2.-XX:+PrintGCDetails
3.2.2.1.推荐使用
3.2.2.2.将创建包含更多信息的详细日志
3.2.2.3.默认情况下是false
3.2.3.-XX:+PrintGCTimeStamps
3.2.3.1.确定GC操作之间的时间
3.2.3.2.时间戳(time stamp)是相对于0的(基于JVM启动的时间)值
3.2.4.-XX:+PrintGCDateStamps
3.2.4.1.确定GC操作之间的时间
3.2.4.2.日期戳(date stamp)是实际的日期字符串
3.2.4.3.日期戳需要格式化,这使得日期戳的效率略低
3.2.5.-Xloggc:filename
3.2.5.1.默认被写入标准输出
3.2.5.2.改变被写入的位置
3.2.5.3.可以自动开启简单GC日志
3.2.6.日志文件的滚动
3.2.6.1.可以限制GC日志中保存的数据量
3.2.6.2.-XX:+UseGCLogFileRotation
3.2.6.2.1.默认关闭的
3.2.6.2.2.开启时
3.2.6.2.2.1.-XX:NumberOfGCLogFiles=N
3.2.6.2.2.2.默认的文件数量是0(意味着无限多)
3.2.6.2.2.3.-XX:GCLogFileSize=N
3.2.6.2.2.4.默认的日志文件大小是0(意味着无限大)
3.2.6.3.示例
3.2.6.3.1. ***-Xloggc:gc.log -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFile=8 -XX:GCLogFileSize=8m***
3.3.在JDK 11中开启GC日志
3.3.1.JDK 11和之后的版本统一使用了Java的新日志功能
3.3.2.-Xlog标志开启
3.3.3.-Xlog:gc*:file=gc.log:time:filecount=7,filesize=8M
3.3.3.1.示例
3.3.3.2.(gc*)设定了应该开启哪些模块的日志
3.3.3.3.(file=gc.log)设置了日志文件的位置
3.3.3.4.(time)是一个修饰符。这个修饰符表示记录信息时要带上时间戳
3.3.3.5.(filecount=7,filesize=8M)设定了输出选项
3.3.3.5.1.当大小达到8 MB时会滚动日志,共保留8个日志文件
3.3.4.GCeasy
3.3.4.1.免费的基本日志解析服务