1. 堆内存参数
在 写参数前,先了解 + 在JVM中表示启用一个功能,— 表示禁用一个功能 ;-XX 对于系统级别的配置,而非 -XX基本对于应用层面上的配置
1.1 GC常用参数
-XX:+PrintGC 虚拟机启动后,GC打印日志
-XX:+UserSerialGC 配置串行回收器
-XX:+PrintGCDetails 显示各区的详细日志信息
-XX: +PrintCommandLineFlags 隐性或显性传给虚拟机参数的输出
1.2堆常用参数
-xms 设置JAVA堆启动初始化参数
-xmx JAVA堆最大化内存
新生代的配置:
-xmn 设置新生代的大小,一般为堆得1/3、1/4
-XX:SurviorRatio 设置新eden/from 比值 例:-XX:SurviorRatio=2
-XX:+NewRatio 老年代/新生代的比值
堆内存溢出日志配置参数(配合使用):
-XX:+HeapDumpOnOutOfMemorryError
-XX:HeapDumpPath=路径/文件名称.dump
1.3 GC回收器描述
- -XX:+UseSerialGC:设置串行收集器
开启串行回收器:
-XX:+UseSerialGC
- -XX:+UseParallelGC:设置年轻代并行收集器
开启并行回收器:
XX:+UseParallelGC
此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。
配置并行收集器的线程数:
-XX:ParallelGCThreads=20
配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等
设置年轻代回收垃圾的最长时间(系统暂停时间):
-XX:MaxGCPauseMillis=100
设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值
自动选择年轻代区大小和相应的Survivor区比例
-XX:+UseAdaptiveSizePolicy
自动选择年轻代区大小和相应的Survivor区比例, 建议使用并行收集器时,一直打开
参数配置例如:
java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20
-XX:MaxGCPauseMillis=100
- -XX:+UseParalledlOldGC:设置并行年老代收集器
开启老年代并行回收器:
-XX:+UseParallelOldGC
配置年老代垃圾收集方式为并行收集。JDK6.0支持对年老代并行收集
例如:
java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC
- -XX:+UseConcMarkSweepGC:设置并发收集器
开启老年代并发收集器:
-XX:+UseConcMarkSweepGC
开启年轻代回收器:
-XX:+UseParNewGC:
设置年轻代为并行收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值
消除空间碎片:
-XX:CMSFullGCsBeforeCompaction 内存空间压缩
-XX:+UseCMSCompactAtFullCollection 老年代压缩
值设置运行多少次GC以后对内存空间进行压缩、整理。
2.栈内存配置
JAVA虚拟机是提供了参数,-Xss指定线程的最大栈空间,也直接决定了函数调用的最大深度。
3.方法区和直接内存
方法区:
-XX:PermSize 设置初始化内存
-XX:MaxPermSize 设置最大内存
直接内存(不必设置):
-XX:MaxDirectMemorySize 设置最大内存
4.垃圾回收和算法
概念:
垃圾回收(Grabage Collection Gc),而GC垃圾是指存于内存中的不会在使用的对象。而回收就是相当于把垃圾清空。垃圾回收有很多算法:引用计数器法、标记压缩法、复制算法、分代、分区等。
4.1引用计数法
核心就是在对象被其它所引用时计数器加1,而医用失效时就减一,但是这种古老的算法无法处理循环医用,比较浪费系统性能
4.2标记清除法
就是分成标记和清除两个阶段进行处理内存中的对象,当然弊端非常大,就是空间碎片问题,不连续的内存空间的工作效率要低于连续的内存空间。
4.3 复制算法
应用在新生代 S0、S1,核心思想就是在内存中空间分成两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的对象复制到到未被使用的内存,之后清除原先块中的所有对象
4.4标记压缩法
在标记清除法基础上做了一个优化,把存活的对象压缩到内存中的一端,而后进行垃圾清理(JAVA中老年代就是使用这个算法)
问:新生代为啥和老年代算法不一样
答:新生代GC回收频率高,对象死亡高
4.5分代算法
根据对象的特点吧内存分成N块,而后根据每个内存的特点使用不同的算法。对于新生代和老年代来说,新生代频率高,没每次耗时间很短,老年代频率低但是耗时长,应该减少GC的次数
4.6分区算法
将内存分成N个小的空间,每个空间都可以独立使用,这样的细粒度的控制一次回收小空间而不是整个空间GC,从而提供性能,并减少停顿时间
4.7 垃圾回收和停顿现象
识别和回收垃圾对象进行内存清理,为了垃圾回收器可以高效的应用,大部分情况下,会要求系统进行一个停顿,终止所有线程没这样才不会产生新的垃圾,同时停顿保持了系统状态在某一瞬间的一致性,更有益的标记垃圾对象
4.8TLAB本地分配缓存
线程专用的分配区域,线程独享,用来避免线程冲突,提高对象分配的效率,对象太大就会直接分配到堆中。
-XX:+UseTLAB 启用TLAB
-XX:+TLABSize 设置TLAB大小
-XX:TLABReFillWasteFraction
-XX:+PrintTLAB 查询TLAB
-XX:ReSizeTLAB 自调整TLABReFillWasteFraction 大小
5.Tomcat调优
5.1 jvm层次调优
修改TOMCAT_HOME/bin/catalina.sh, 一定加在catalina.bat最前面。
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=512m -XX:MaxPermSize=1024m -XX:MaxNewSize=512m"
5.2 配置优化
修改TOMCAT_HOME/conf/server.xml
原生:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
//1、-----打开Tomcat默认被注释的连接池配置-------------------------
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
//2、-----配置Tomcat连接参数------------------------
在Connector中指定使用共享线程池
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="1000"
minSpareThreads="100"
acceptCount="1000"
maxConnections="1000"
connectionTimeout="20000"
maxHttpHeaderSize="8192"
tcpNoDelay="true"
compression="on"
compressionMinSize="2048"
disableUploadTimeout="true"
redirectPort="8443"
enableLookups="false"
URIEncoding="UTF-8" />
protocol设置:
Tomcat 8 设置 nio2 更好:org.apache.coyote.http11.Http11Nio2Protocol(无用则配置下面方式)
Tomcat 6、7 设置 nio 更好:org.apache.coyote.http11.Http11NioProtocol
enableLookups: 是否反查域名【禁用DNS查询】,默认值为true。为了提高处理能力,应配置为false
connnectionTimeout: 通常可配置为30000毫秒。
maxKeepAliveRequests:maxKeepAliveRequests="1", 避免tomcat产生大量的TIME_WAIT连接,从而从一定程度上避免tomcat假死
在Nginx+tomcat的架构中,禁用AJP连接器 注释代码即可
5.3组件优化(不了解)
Tomcat 连接器的三种方式: bio、nio 和 apr,三种方式性能差别很大,apr 的性能最优, bio 的性能最差。而 Tomcat 7 使用的 Connector 默认就启用的 Apr 协议,但需要系统安装 Apr 库,否则就会使用 bio 方式