Java虚拟机调优
2018-08-10
本文总阅读量:次
Java内存结构
- 一个线程对应一个栈,一个方法对应一个栈帧
- 持久代perm也叫做方法区,永久区
- 永久区存放class文件,静态变量,字符串常量,方法和执行引擎都去永久区找
堆内存
- new出来的对象如果很大直接放到老年代中,否则放到新生代
- 发生gc新生代没有被回收的会被放到survivor区
- 再次发生gc,新生代没有被回收的和survivor没有被回收的,放到了另一个survivor区
- 往复循环
- 两个survivor会被叫为from,to或者s0,s1
- 比例设置
GC如何确定垃圾
- 强引用,软引用,虚引用,弱引用
- main方法里的对象可以作为roots,class加载器也是
垃圾收集算法
- Mark-Sweep标记清除,实际上不是擦除,而是做了标记,有内存碎片问题,导致需要fullGC来整理,耗费时间
- Copying复制,效率高,但是浪费内存空间,survivor区就是这个算法,因为新生代一般剩下的不多
- Mark-Compact标记压缩,老年代用这个算法,因为每次更改的都不多
jvm采用分代算法
- new
- 存活对象少
- 使用copying,占用内存空间也不大,效率也高
- old
- 垃圾少
- 一般使用mark-compact
JVM参数
- -标准参数,所有jvm都应该支持
- -X非标,每个jvm实现都不同
- -XX不稳定参数,下一个版本可能会取消
垃圾收集器
- Serial Collector
- Parallel Collector 并发量大,每次垃圾收集停顿时间长
- CMS Collector 停顿时间短
- G1 Collector 中合并发量大和停顿时间短
java对象的分配
- 占用1%是为了减少加锁,要不然多线程要加锁影响速度
- 逃逸指的是对象在线程外部也有引用,线程结束后无法回收
常用参数设置
- 堆设置
- -Xms:初始堆大小
- -Xmx:最大堆大小
- -Xss:线程栈大小
- -XX:NewSize=n:年轻代大小
- -XX:NewRatio=n:设置年轻代和年老代的比值。如3:代表年轻:年老为1:3,年轻代占整个年轻代年老代的1/4
- -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值,注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5,比2因为有两个
- -XX:MaxPermSize=n:设置持久代大小
- 收集器设置
- -XX:+UseSerialGC:设置串行收集器
- -XX:+UseParallelGC:设置并行收集器
- -XX:+UseConcMarkSweepGC:设置并发收集器
- 垃圾回收统计信息
- -XX:+PrintGC
- -XX:+PrintGCDetails
- -Xloggc:filename
- -Xss的理解
- 该参数指的是栈中每个线程的空间大小,即线程栈的大小
- 如果分配的小,那么可启动的线程多,并发性好
- 如果分配的大,那么递归调用就可以很深,但是可启动的线程变少,并发性差
典型tomcat优化配置
- set JAVA_OPTS=
- -Xms4g
- -Xmx4g
- -Xss512k
- -XX:+AggressiveOpts //凡是能优化的都开启
- -XX:+UseBiasedLocking
- -XX:PermSize=64M //jdk1.8取消了
- -XX:MaxPermSize=300M //class越来越多,最大给300M
- -XX:+DisableExplicitGC //System.gc()不起作用,因为有人调用会打乱调优
- 如果服务器上只有一个java虚拟机程序,可以让他尽量占内存
- 如果业务中new出来的东西特别多,Eden区要调大一点
- 业务中有很多对象在不停的运行,老年代的多,就把老年代的调多,调调比例
JMeter和Load Runner等性能测试工具
- 修改catalina.bat做调优