参考链接:https://blog.csdn.net/zhoutao198712/article/details/7783070
垃圾回收器:https://www.cnblogs.com/shmilyToHu/p/7341951.html
https://www.cnblogs.com/grey-wolf/p/9217497.html
垃圾回收期算法:https://www.cnblogs.com/chenpt/p/9803298.html
线上问题排查:https://www.jianshu.com/p/778ffa2ab881
查看linux内存:
$ free -m
$ vmstat -s
1. java常见配置参数
1.1 常见参数
堆设置:-Xmx和-Xms
年轻代设置(young):-XX:NewSize和-XX:MaxNewSize 或者:-Xmn(优先级高于前两个,推荐整个堆大小的3/8)
老年代设置(old):空间大小可以基于young代的大小进行计算(堆大小-年轻代大小)
–XX:SurvivorRatio :Eden区域和Survivor区域(From幸存区或To幸存区)的比例,默认为8,也就是说Eden占新生代的8/10,From幸存区和To幸存区各占新生代的1/10
-XX:NewRatio 是“老年代 / 新生代”的比例,默认值为 2;
永久代设置(permanent):-XX:PermSize和-XX:MaxPermSize
-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
JVM runtime:
client runtime:
server runtime:
tiered server runtime:-server -XX:+TieredCompilation
JDK8 中,永久代被完全的移除了,包括相关参数 -XX:PermSize / -XX:MaxPermSize。改用 Metaspace,通过参数-XX:MetaspaceSize / -XX:MaxMetaspaceSize / -XX:CompressedClassSpaceSize 设定;
MaxTenuringThreshold:Survivor 区交换多少次会被放入old区(默认15)
1. 默认的,新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2
2. VM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块 Survivor 区域是空闲着的。因此,新生代实际可用的内存空间为 9/10 ( 即90% )的新生代空间。
1.2 经验配置
old代活动对象:活动对象的大小是应用处于稳定运行状态时,长时间存活数据占用的Java堆的空间大小。换句话说,就是应用稳定运行是,在FullGC之后,old代和permanent代的空间大小。
计算方法:为了保证能够准确的评估应用的活动对象大小,最好的做法是多看几次FullGC之后Java堆空间的大小,保证FullGC是发生在应用处于稳定运行的状态。
测试环境下,出发full gc方法:
1. Java监控工具来触发FullGC,比如使用VisualVM和JConsole
2.jmap命令:jmap -histo:live 348
1. Java堆大小的初始化值和最大值(通过-Xms和-Xmx选项来指定)应该是old代活动对象的大小的3到4倍。
2. permanent的初始值和最大值(-XX:PermSize和-XX:MaxPermSize)应该permanent代活动对象大小的1.2到1.5倍
3. 另外一个常规是,young代空间应该是old代活动对象大小的1到1.5倍。那么在这里例子中,young代的大小可以设置为295M到
4. 老年代的内存大小设置为老年代存活对象的2-3倍。
2. 垃圾回收
2.1 分代回收
Full GC:old代和permanent:old和permanent都可能出发full GC,并且无论哪个触发,都会回收old和permanent;Full GC时,也会出发young GC,除非设置:-XX:+ScavengeBeforeFullGC,关闭FullGC的时候young代的垃圾回收。
Young GC:回收年轻代
2.2 垃圾回收器
使用吞吐量垃圾回收器通过设置-XX:+UserParallelOldGC命令行选项,如果你使用的HotSpot VM不支持的这个选项,那么就使用-XX:+UserParallelGC
初始化和最大的堆大小可以通过-XX:+PrintCommandLineFlags来查看。-XX:+PrintCommandLineFlags打印出在HotSpot VM初始化的时候选择的初始值和最大值比如-XX:InitialHeapSize=<n> -XX:MaxHeapSize=<m>,这里n表示初始化的java堆大小值,m表示java堆的最大值。
2. java优化命令
3. java工具
4. JVM优化实战
1. 测试基础设施
内存占用、延迟、吞吐量以及启动时间
2.对系统需求进行优先级排序
3.选择JVM部署模型
单实例JVM
多实例JVM
4. JVM runtime选择
5. 32位或者64位JVM选择
6. 选择初始的垃圾回收器
serial,throughput,mostly concurrent以及garbage first。
使用throughput垃圾回收器可以通过HotSpot VM的命令行参数来指定:-XX:+UseParallelOldGC或者-XX:+UseParallelGC
如果在你的HotSpont VM的版本上-XX:+UseParallelOldGC选项不能使用,使用+XX:UseParallelGC。两者的不同点在于,-XX:+UseParallelOldGC促发了多线程young代的垃圾回收和多线程old代的垃圾回收,也就是说minor垃圾回收和full垃圾回收都是多线程的。+XX:+UseParallelGC仅仅是young代的垃圾回收是多线程的,old代的垃圾回收的单线程的。因此,如果你想要young代和old代的垃圾回收都是多线程的就配置-XX:+UserParallelOldGC。而且-XX:+UserParallelOldGC是兼容-XX:+UseParallelGC。
7. GC优化基础
垃圾回收性能指标:
吞吐量:衡量垃圾回收器运行在性能峰值的时候不需要关心垃圾回收器暂停的时间或者需要占用内存的能力。
延迟:衡量垃圾回收器最小化甚至消灭由垃圾回收器引起的暂停时间和应用抖动的能力。
内存占用:衡量为了高效的运行,垃圾回收器需要的内存。
一项指标的提升,往往需要牺牲其他一项或者两项指标。换一句话说,一项指标的妥协通常是为了支持提升其他一项或者两项指标。然而,对于大多数应用来说,很少有3项指标都非常重要,通常,一项或者两项比其他的更重要。
由于始终需要各种权衡,那么知道哪项指标对应用是最有必要的就显得非常重要。
垃圾回收原则:
在minor垃圾回收器中,最大量的对象被回收,这个被称为Minor GC回收原则。秉承这个原则可以减少由应用产生的full垃圾回收数量和频率,Full垃圾回收往往需要更长的时间,以致于应用无法达到延迟和吞吐量的需求。
更多的内存分配给垃圾回收器,也就是说更大的Java堆空间,垃圾回收器和应用在吞吐量和延迟上会表现得更好,这条原则被称为GC最大内存原则。
优化JVM垃圾回收器的3个指标中的2个,这个被称为2/3 GC优化原则。
从垃圾回收器获取监控信息,是优化JVM的重要操作。收集垃圾回收器信息的最好办法就是收集日志。这个意味着通过HotSpot VM的命令行选项可以收集垃圾回收器的统计信息。开启垃圾回收器日志(即使在生产环境)是很好的主意,其实开启垃圾回收器的开销很小而且可以提供丰富的信息,这些信息和垃圾回收器应用事件或者JVM事件有关系,比如说:一个应用在运行过程中出现了一个比较长的暂停,如果有垃圾回收信息,就可以判断出是垃圾回收器引起的暂停还是应用进行的其他操作引起的暂停。
有很多的HotSpot VM命令行选项可以用在垃圾回收的日志上面 ,例如: -XX:+PrintGCTimeStamps -XX:打印出垃圾回收发生的时间是距离HotSpot VM启动时间的秒数
+PrintGCDetails 提供了垃圾回收特有的统计信息而且具体信息依赖于使用的垃圾回收器类型
-Xloggc:<filename>表示垃圾回收器的信息输出到叫<filename>的文件