jvm性能调优并用Jmeter测试
java内存结构
方法区在java8里面改成永久区
堆内存的构成
eden 伊甸园
survivor 幸存者
当我们new对象的时候 特别大的对象 放入老年代 ,其他普通的对象 放入新生代,内部使用GC 垃圾回收器 来进行收集和整理的,如果经历过第一次GC之后,eden当中的某个对象并没有被回收(因为还有一个引用老指向它),那么此时该没有被回收对象就会从eden区进入其中的一个survivor区(这里以左边的为例),那么在第二次GC的时候,(该survivor区(左边的)的对象会被拷贝到另外一个survivor区(右边的),同时第二次未被回收的对象,也会进入survivor区(右边的)),再经历一次GC,如果eden区还有对象没有被回收,(此时由于左边的survivor中所有的对象已经被复制到右边的survivor区,那么 这次右边的survivor中的内存 复制到左边,同时没有被回收的对象放入左边的survivor,再下一次GC也会是同样的过程,循环往复.
两个survivor也可以叫做from区和to区,from区和to区互相的角色总是在不停的转换,(内存被拷贝来 拷贝去…)每个时刻 都会有一个survivor区为空, 书中说是15次复制,如果经历了很多次的GC survivor区中还有没被回收掉 就会被放入老年代,
堆内存参数调整
所谓的调优 主要是两块 第一块 对内存的调整,第二块 垃圾收集的调整
用visualVM观察虚拟机堆信息
垃圾收集算法
**什么是垃圾 **
没有任何引用指向的对象 被叫做垃圾 画个图 简单说明
不是完全对,在我们的程序里,如果右a,b两个对象 内部有一个引用指向a,也有一个引用指向b,但是 除了这两个引用以外,没有人指向这两对象,那么这两对象叫做一堆垃圾,此外 还有环形垃圾 a->b->c->d ,d->a,(软引用 弱引用 虚引用)
GC如何确定垃圾
用引用计数 这样不行 因为会有循环引用的问题
采用正向可达的算法来确定垃圾,(从roots对象计算可以到达的对象,都不是垃圾,剩下的都是垃圾)
回收算法
Mark-sweap 标记清除
通过正向可达一系列操作,找到垃圾 并把它们标记,再由垃圾回收器(另外一个线程)回收(清除)清除后 再把不可用的内存 标记为可用,但是这样会导致内存不连续 碎片化,如果一个特别大的对象 需要连续的空间来存储,此时 就要发生父GC (把所有可食用的对象复制到一端区 进行压缩,腾出空间来存放此大对象)这样效率太低
Copying(复制算法)
比例问题,eden:survivor 一般为8:1:1
eden+survivor:tenured 1:3 或3:8 或1:2
区域的调整要根据具体的应用来,
Mark-compact(标记压缩)
标记压缩,把不是垃圾的内存标记起来,都往一端压缩,压缩到一端后 腾出空间放其他对象,这种算法 效率比复制算法略低,一般被用于老年代中(因为在老年代中的对象一直不消失,产生的垃圾比较少 采用标记压缩效率比较高),也就是说在新生代eden和survivor之间用的是copy的算法, (因为新生代中 基本上大部分的对象都会被回收,剩下的对象放入survivor区 你占用内存较少)
jvm参数
– 默认参数
–X 非标准
–XX 不稳定参数
垃圾收集器
串行收集器 单线程收集 XX:+UseSerialGC
并行收集器(paraillel) 多线程处理 XX:+UseParallelGC
不过每次垃圾收集完 虚拟机需要停顿,
并发收集器 XX:+UseConcMarkSweepGC (cms收集器,除了多线程之外 并发来做,分成好多个区) 并发量大,停顿时间短,
G1 收集器 –XX:+UseG1GC (被java9作为默认的收集器)
不仅停顿短,同时并发量大
不开逃逸分析,就不能分配到栈上
堆设置
-Xms 初始堆大小
-Xmx 堆最大大小
-Xss 线程栈大小
-XX:NewSize=n 设置年轻代大小
-XX:NewRatio=n 设置年轻代和老年代的比值, 如3 表示年轻代和老年代的比值为1:3 年轻代占整个年轻代老年代之和的1/4
-XX:SurvivorRatio=n
年轻带中两个survivor的比值,如3 表示Eden:survovor = 3:2 一个survovor占整个新生代的1/5 如8 表示Eden:survivor =8:2 survivor占整个新生代的1/10
-XX:MaxPermsize=n 设置持久代大小
收集器设置
-XX:+UseSerialGC 设置使用串行收集器
-XX:+UseParallelGC 设置使用并行收集器
-XX:+UseConcMarkSweepGC 设置使用并发收集器
垃圾回收统计信息
-XX:+printGC
-XX:+printGCDetails
-Xloggc:filename 将jvm信息打印进文件
典型tomcat优化配置
调优配置tomcat
set JAVA_OPTS=
-Xms=4g 初始堆大小4g
-Xmx=4g 堆最大大小4g
-Xss512k 线程栈512k
-XX:+AggressiveOpts 优化 进攻性的 凡是虚拟机里面能用到的优化选项都用上
-XX:+UseBiasedLocking 偏置锁 一个锁没有被锁定的情况下 线程去访问的时候一个优化的选项
-XX:MaxPermSize=300M 永久区的大小 最大给300M
-XX:+DisableExplicitGC 关闭显示调用gc 意思是不让显示的调用gc
无监控不调优,一定要使用监控工具
首先 先确定服务器上有几个虚拟机,服务器的内存大小 ,然后确定给tomcat多大的内存,比如就跑了一个tomcat 那么只需把jvm设置为最大内存
使用Jmeter进行测试
下载Jmeter,启动并测试,这里我们以本地tomcat为例,不部署任何项目,访问一下example jsp页面 并启动2000个线程 测试一下吞吐量
并添加监控图表
我们先不加任何调优参数 看一下服务器每秒处理http请求的吞吐量
下面 我们添加jvm参数,然后再启动tomcat 测试并发