本文是基于jdk1.8,其他版本稍有不同
JVM参数类型
(1)标准参数
-help
-server -client
-version -showversion
-cp -classpath
(2)X参数
非标准化参数
-Xint:解释执行
-Xcomp:第一次使用就编译成本地代码
-Xmixed:混合模式,由JVM自己来决定是否编译成本地代码
(3)XX参数
非标准化参数
相对不稳定
主要用于JVM调优和Debug
XX参数分类
(1)Boolean类型
格式:-XX:[+-]
比如:-XX:+UseConcMarkSweepGC
-XX:+UseG1GC
(2)非Boolean类型
格式:-XX:
比如:-XX:MaxGCPauseMillis=500
XX:GCTimeRatio=19
jps工具
查看java进程
#常用指令 |
jinfo工具
查看Java进程运行的JVM参数
#常用指令 |
jstat工具
监控进程的类装载、内存、垃圾收集、JIT编译等运行数据
jstat <参数> pid time(ms) count
#每隔1s显示类装载信息,输出10次 |
-gc输出结果
S0C、S1C、S0U、S1U:S0和S1的总量与使用量
EC、EU:Eden区总量与使用量
OC、OU:Old区总量与使用量
MC、MU:Metaspace区总量与使用量
CCSC、CCSU:压缩类空间总量与使用量
YGC、YGCT:YoungGC的次数与时间
FGC、FGCT:FullGC的次数与时间
GCT:总的GC时间
查看JVM运行时的参数
(1)PrintFlagsFinal
java -XX:+PrintFlagsFinal -version |
(2)jinfo
jinfo -flag MaxHeapSize 14589 |
JVM内存结构
内存溢出演示
@Controller |
为了更快的看出效果,设置JVM参数:-Xmx32M -Xms32M
导出内存映像文件
(1)内存溢出时自动导出
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./
(2)使用jmap命令手动导出
jmap -dump:format=b,file=heap <pid> |
Tomcat优化
线程优化
相关文档:docs/config/http.html
(1)maxConnections:最大连接数,tomcat能够最大处理的最大连接数
(2)acceptCount:默认是100,如果请求超过了maxConnections,可以配置一个队列,将连接压到队列里。(不需要太大,太大没有意义)
(3)maxThreads:工作线程数,默认值是200,同一个时间点上能够同时处理的并发请求数
(4)minSpareThreads:最小空闲的工作线程。不能设置太小,万一请求突然变多,线程数来不及增加。
配置优化
(1)autoDeploy:当tomcat运行时,是否需要周期性检查有新的web应用,来部署新的应用。生产环境,建议设置为false
(2)enableLookups:是否需要tomcat进行DNS域名解析。生产环境,建议设置为false
(3)reloadable:是否需要tomcat监控/WEB-INF/classes/ and /WEB-INF/lib的变化。生产环境,建议设置为false
(4)tomcat有3中方式启动:bio、nio、apr
BIO:bio是阻塞式IO操作,使用java io技术,即每一个请求都要创建一个线程来进行处理。缺点:并发量高时,线程数较多,占资源
NIO:使用java nio技术,能够通过少量的线程处理大量的请求,nio是基于java中非阻塞IO操作的API实现,比传统的i/o处理方式有更高的并发运行性能
APR(Apache Portable Runtime/Apache可移植运行时库):apr是从操作系统级别解决异步IO问题,大幅度提高服务器的并发处理性能,也是Tomcat生产环境运行的首选方式
tomcat低版本是使用BIO的,tomcat8以后默认使用NIO方式,在service.xml文件中找到此处
<Connector port="8091" protocol="HTTP/1.1" |
修改成下面这个,可以使用apr的模式启动
<Connector port="8091" protocol="org.apache.coyote.http11.Http11AprProtocol" connectionTimeout="20000" redirectPort="8443" /> |
Session优化
如果没有使用原生的Session,并且页面是使用JSP写的,建议禁用Session
#JSP禁用Session |
Nginx优化
配置线程数和并发数
worker_processes 4; #cpu |
配置后端Server的长连接
upsteam server_pool{ |
配置压缩
gzip on; |
操作系统优化
#配置文件/etc/sysctl.conf |
#配置文件/etc/security/limits.conf |
其他优化
sendfile on; #减少文件在应用和内核之间拷贝 |
GC调优
常用参数
-Xms -Xmx:最小堆内存 最大堆内存
-XX:NewSize -XX:MaxNewSize:新生代大小 最大新生代大小
-XX:NewRatio -XX:SurvivorRatio:young区与old区的比例 Eden区域和Survivor区域
-XX:MetaspaceSize -XX:MaxMetaspaceSize:Metaspace区域大小 最大Metaspace区域大小
-XX:+UseCompressedClassPointers:是否启用压缩的类指针,启用之后就会产生CCS区域(默认占有1024M大小)
-XX:CompressedClassSpaceSize:设置压缩区域大小
垃圾回收算法
(1)标记-清除
定义:算法分为“标记”和“清除”两个阶段,首先标记出所有需要回收的对象,在标记完成后统一回收所有
缺点:效率不高,标记和清除两个过程的效率都不高。产生碎片,碎片太多会导致提前GC。
(2)复制
定义:它将可用内存按容量分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完时,它将还存活着的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。
优缺点:实现简单,运行高效,但是空间利用率低。
(3)标记-整理
定义:标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存
优缺点:没有了内存碎片,但是整理内存比较耗时。
分带垃圾回收
Young区用复制算法
Old区对象存活时间较长,采用标记清除或标记整理算法
对象分配
对象优先在Eden区分配
大对象直接进入老年代:-XX:PretenureSizeThreshold
长期存活的对象进入老年代:-XX:MaxTenuringThreshold -XX:+PrintTenuringDistribution -XX:TargetSurvivorRatio
垃圾收集器
(1)串行收集器Serial:Serial、Serial Old
进行垃圾收集时,必须暂停所有工作线程,直到完成,即”Stop The World”;
-XX:+UseSerialGC -XX:+UseSerialOldGC |
(2)并行收集器Parallel:Parallel Scavenge、Parallel Old,吞吐量优先
Server模式下的默认收集器
#开启参数 |
(3)并发收集器Concurrent:CMS、G1,响应时间优先
#开启参数 |
#CMS的相关参数 |
垃圾收集器的选择
(1)优先调整堆的大小让服务器自己来选择
(2)如果内存小于100M,使用串行收集器
(3)如果是单核,并且没有停顿时间的要求,串行或者JVM自己选
(4)如果允许停顿时间超过1秒,选择并行或者JVM自己选
(5)如果响应时间必须小于1秒,选择并发收集器
G1垃圾收集器
(1)定义
将内存划分为一个个相等大小的内存分区,回收时则以分区为单位进行回收,存活的对象复制到另一个空闲分区中。由于都是以相等大小的分区为单位进行操作,因此G1天然就是一种压缩方案(局部压缩);
Region:内存分区
SATB:它是通过Root Tracing得到的,GC开始时后存活对象的快照
RSet:记录了其他Region中对象引用本Region中对象的关系,属于points-into结构(谁引用了我的对象)
(2)YoungGC
1)新对象进入Eden区
2)存活对象拷贝到Survivor区
3)存活时间达到年龄阈值时,对象晋升到Old区
而G1垃圾收集器不是FullGC,是MixedGC(回收所有Young和部分Old)
(3)MixedGC时机
InitiatingHeapOccupancyPercent:堆占有率达到这个值则触发global concurrent marking(全局并发标记),默认值45%
G1HeapWastePercent:在global concurrent marking标记之后,可以知道区有多少空间要被回收,在每次YGC之后和再次发生MixedGC之前,会检查垃圾占比是否达到此参数值,只有达到了,下次才会发生MixedGC
#MixedGC相关参数 |
(4)注意
年轻代大小:避免使用-Xmn、-XX:NewRatio等显式设置Young区大小,会覆盖暂停时间目标
暂停时间目标:暂停时间不要太苛刻,其吞吐量是90%的应用程序时间和10%的垃圾回收时间,太苛刻会直接影响到吞吐量