Java调优总结

JVM

JVM内存结构

在这里插入图片描述

垃圾回收算法

  • 思想:枚举根节点,做可达性分析
  • 根节点:类加载器、Thread、虚拟机栈的本地变量表、static成员、常量引用、本地方法栈的变量
标记清除算法

算法:是分为"标记"和”清除“两个阶段,首先标记出所有需要回收的对象,在标记完成后统一回收所有

缺点:效率不高,标记和清除两个过程的效率都不高;产生碎片,碎片太多会导致提前GC

复制算法

它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过得内存空间一次清理掉

优缺点:实现简单、运行高效,但是空间利用率低

标记整理算法

标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,让后直接清理掉端边界以外的内存

优缺点:没有了内存碎片,但是整理起来比较耗时

分代垃圾回收算法

Young区用复制算法

Old区用“标记-清除”或者“标记整理”算法

对象分配

  • 对象优先在Eden区分配
  • 大对象直接进入老年代:-XX:PretenureSizeThreshold
  • 长期存活对象进入老年代:-XX:MaxTenuringThreshold -XX:+PrintTenuringDistribution -XX:TargetSurvivorRatio

垃圾收集器

  • 串行收集器Serial:Serial、Serial Old

    -XX:+UseSerialGC -XX:+UseSerialOldGC
    
  • 并行收集器Paralle:Parallel Scavenge、Parallel Old,(是吞吐量优先收集器)

    -XX:+UseParallelGC 手动开启 (-XX:+UseParallelOldGC),Server模式默认开启
    -XX:ParallelGCThreads=<N> 多少个GC线程(CPU<8?N=CPU:N=5/8)
    
    Parallel Collector Ergonomics,会按以下顺序自动调整
    	-XX:MaxGCPauseMillis=<N>
    	-XX:GCTimeRatio=<N>
    	-Xmx<N>
    动态内存调整
    	-XX:YoungGenerationSizelncrement=<Y> #20%
    	-XX:TenuredGenerationSizeLncrement=<T> #20%
    	-XX:AdaptiveSizeDecrementScaleFactor=<D>
    
  • 并发收集器:Concurrent:CMS、G1,(是停顿时间优先收集器)

    CMS Collector(老年代收集器)
    	并发收集
    	低停顿 低延迟
    CMS垃圾收集过程
    	1.CMS initial mark:初始标记Root,STW
    	2.CMS concurrent mark:并发标记
    	3.CMS-concurrent-preclean:并发预清理
    	4.CMS remark:重新标记,STW
    	5.CMS concurrent sweep:并发清除
    	6.CMS-concurrent-reset:并发重置
    CMS缺点
    	CPU敏感
    	浮动垃圾
    	空间碎片
    CMS相关参数
    	-XX:ConcGCThreads:并发的GC线程数
    	-XX:+UseCMSCompactAtFullCollection:FullGC之后做压缩
    	-XX:CMSFullGCsBeforeCompaction:多少次FullGC之后压缩一次
    	-XX:CMSInitiatingOccupancyFraction:触发FullGC
    	-XX:+UseCMSInitiatingOccupancyOnly:是否动态可调
    	-XX:+CMSScavengeBeforeRemark:FullGC之前先做YGC(YoungGC)
        -XX:+CMSClassUnloadingEnabled:启用回收Perm区
    ICMS
    	适用于单核或双核(jdk8已弃用)
    -----------------------------------------------------------------------	
    G1 Collector(新生代和老年代收集器)
    简介:
    	The Garbage-First (G1) collector is a server-style garbage collector, targeted for multi-processor machines with large memories. It meets garbage collection (GC) pause time goals with a high probability, while achieving high throughput. The G1 garbage collector is fully supported in Oracle JDK 7 update 4 and later releases. The G1 collector is designed for applications that:
    	Can operate concurrently with applications threads like the CMS collector.
    	Compact free space without lengthy GC induced pause times.
    	Need more predictable GC pause durations.
    	Do not want to sacrifice a lot of throughput performance.
    	Do not require a much larger Java heap.
    G1的几个概念
    	Region
    	STAB:Snapshot-At-The-Beginning,它是通过Root Tracing得到的,GC开始时候存活对象的快照
    	RSet:记录了其他的Region中的对象引用本Region中的对象关系,属于points-into结构(谁引用了我的对象)
    	
    YoungGC
    	新对象进入Eden区
    	存活对象拷贝到Survivor区
    	存活时间叨叨年龄阈值时,对象晋升到Old区
    	
    MixedGC
    	不是FullGC,回收所有Young区和部分Old区
    	global concurrent marking
    		1.Initial marking phase:标记GC Root,STW
    		2.Root region scanning phase:标记存活Region
    		3.Concurrent marking phase:标记存活的对象
    		4.Remark phase:重新标记,STW
    		5.Cleanup phase:部分STW
    	MixedGC调优
    		InitiatingHeapOccupancyPercent:占有率达到这个数值则触发global concurrent marking,默认45%
            G1HeapWastePercent:在global concurrent marking结束之后,可以知道区多少空间要被回收,在每次YGC之后和再次发生MixedGC之前,会检查垃圾占比是否达到此参数,只有达到了,下次才会发生MixedGC
          	G1MixedGCLiveThresPercent:Old区的region被回收时存活对象占比
          	G1MixedGCCountTarget:一次global concurrent marking之后,最多执行MixedGC的次数
          	G1OldCSetRegionThresholdPercent:一次MixedGC中能被选入CSet的最多old区的region数量
    
    常用参数
    	-XX:+UseG1GC #开启G1
    	-XX:G1HeapRegionSize=n #region的大小,1-32M,2048-XX:MaxGCPauseMillis=200 #最大停顿时间
    	-XX:G1NewSizePercent、-XX:G1MaxNewSizePercent
    	-XX:G1ReservePercent=10 #保留防止to space溢出
    	-XX:ParallelGCThreads=n #SWT线程数
    	-XX:ConcGCThreads=n #并发线程数=1/4*并行线程数
    G1最佳调试
    	年轻代大小:避免使用-Xmn、-XX:NewRation等显示设置,Young区太小,会覆盖暂停时间目标
    	暂停时间目标:暂停时间不要太严苛,其吞吐量目标是90%的应用程序时间和10%的垃圾回收时间,太严苛会直接影响到吞吐量
    	
    需否需要切换到G1
    	50%以上的堆被存活对象占用
    	对象分配和晋升的速度变化非常大
    	垃圾回收时间特别长,超过1S
    

    Concurrent Mark Sweep (CMS) Collector

    Garbage-First Garbage Collector Tuning

在这里插入图片描述
收集器调优指南
Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide

 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。适合科学计算、后台处理等弱交互场景

 并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),垃圾收集线程在执行的时候不会停顿用户线程的运行。适合对响应时间有要求的场景,比如Web

 停顿时间:垃圾收集器做垃圾回收中断应用执行的时间 -XX:MaxGCPauseMillis

 吞吐量:花在垃圾收集的时间和花在应用时间的占比 -XX:GCTimaRatio=<n>,垃圾收集时间占:1/(1+n)

GC日志格式

日志参数
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution

ParallelGC调优

  1. 打印GC日志
  2. 根据日志得到关键性能指标(GCViewer)
  3. 分析GC原因,调优JVM参数
调优测试
ParallelGC调优指导原则

ParallelGC调优先参考

  • 除非确定,否则不要设置最大堆内存
  • 优先设置吞吐量目标
  • 如果吞吐量目标达不到,调大最大内存,不能让OS使用Swap,如果仍然达不到,降低目标
  • 吞吐量能达到,GC时间太长,设置停顿时间的目标
  1. 初始设置
-XX:DisableExplictGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$CATALINA_HOME/logs/ -XX:+PrintGCDetails -XX:PrintGCTimeStamps -XX:+PringGCDateSamps -Xloggc:$CATALINA_HOME/logs/gc.log
  1. 设置Metaspace大小

    -XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=64M
    
  2. 添加吞吐量和停顿时间参数

    -XX:GCTimeRatio=99 -XX:MaxGCPauseMillis=100
    
  3. 修改动态扩容增量

    -XX:YoungGenerationSizelncrement=30 #30%
    

G1调优

    相关参数
    -XX:+UseG1GC -Xms128M -XmX128M -XX:MetaspaceSize=64M -XX:MaxGCPauseMills=100 -XX:UseStringDeduplication -XX:StringDeduplicationAgeThreshold=3
    

Tomcat优化

  • 内存优化(略)
  • 线程优化
  • 配置优化

线程优化

tomcat/webapps/docs/config/http.html

maxConnections:The maximum number of connections that the server will accept and process at any given time.
acceptCount:The maximum queue length for incoming connection requests when all possible request processing threads are in use.
maxThreads:The maximum number of request processing threads to be created by this Connector, which therefore determines the maximum number of simultaneous requests that can be handled. 
minSpareThreads:The minimum number of threads always kept running. If not specified, the default of 10 is used.

配置优化

tomcat/webapps/docs/config/host.html

autoDeploy:This flag value indicates if Tomcat should check periodically for new or updated web applications while Tomcat is running.

tomcat/webapps/docs/config/http.html

enableLookups:false

tomcat/webapps/docs/config/context.html

reloadable:false

tomcat/conf/server.xml

protocol="HTTP/1.1"

Session优化,如果是JSP

session=false

Nginx优化

  • 增加工作线程数和并发连接数
  • 启用长连接
  • 启用缓存、压缩
  • 操作系统优化

配置线程数和并发连接数

worker_processes 4;#根据cpu个数
events {
    worker_connections 1024;#每一个进程打开的最大连接数,包括Nginx与客户端和Nginx与upstream之间的连接
    multi_accept on;#可以一次建立多个链接
    use epoll;
}

配置后端Server的长连接

upstream server_poll{
    server localhost:8080 weight=1 max_fails=2 fail_timeout=30s;
    server localhost:8081 weight=1 max_fails=2 fail_timeout=30s;
    keepalive 300;#300个长连接
}
location / {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "upgrade";
    proxy_pass http://server_poll/;
}

配置压缩

gzip on;
gzip_http_version 1.1;
gzip_disable "MSIE[1-6]\.(?!.*SV1)";
gzip_proxied any;
gzip_types text/plain text/css application/javascrip application/x-javascript application/json application/xml application/vnd.ms-fontobject application/x-font-ttf application/svg+xml application/x-icon;
gzip_vary on;#Vary:Accept-Encoding
gzip_static on;#如果有压缩好的,直接使用

操作系统优化

配置文件:/etc/sysctl.conf

sysctl -w net.ipv4.tcp_syncookies=1#防止一个套接字在有过多试图连接到达时引起过载
sysctl -w net.core.somaxconn=1024#默认128,连接队列
sysctl -w net.ipv4.tcp_fin_timeout=10#timewait超时
sysctl -w net.ipv4.tcp_tw_reuse=1#os直接使用timewait的连接
sysctl -w net.ipv4.tcp_tw_recycle=0#回收禁用

其他优化

sendfile on;#减少文件在应用和内核之间拷贝
tcp_nopush on;#当数据包达到一定大小再发送
tcp_nodelay off;#有数据随时发送

代码优化

  • 尽量重用对象,不要循环创建对象,比如:for循环字符串拼接

  • 容器类初始化时指定长度

    List<String> list = new ArrayList<String>(10);
    Map<String,String> map = new HashMap<String,String>(20);
    
  • ArrayList遍历快,LinkedList增删快

  • 集合遍历尽量减少重复计算

    for(int i=0,len=list.size();i<len;i++){}
    
  • 使用Entry遍历Map

    for(Map.Entry<String,String> entry:map.entrySet()){
        String key = entry.getKey();
        String value = entry.getValue();
    }
    
  • String尽量少用正则表达式

    replace() VS replaceAll();
    split();
    
  • 大数组复制用System.arraycopy

  • 尽量使用基本类型,减少转换

  • 不手动调用Systemgc()

  • 及时清除过期对象的引用,防止内存泄漏

  • 尽量使用局部变量,减小变量的作用域

  • 尽量使用非同步容器 ,ArrayList VS Vector

  • 尽量减小同步作用范围,synchronized方法VS synchronized 代码块

  • ThreadLocal缓存线程不安全的对象(不用经常new对象),SimpleDateFormat

  • 尽量使用延迟加载,如:静态内部类单例模式

  • 减少使用反射,加缓存

  • 尽量使用连接池、线程池、对象池、缓存

  • 及时释放资源,I/O流、Socket、数据库连接

  • 慎用异常,不要用抛异常来表示正常的业务逻辑

  • 日志输出使用不同级别

  • 日志中参数拼接使用占位符

    log.info("orderId:" + orderId);不推荐
    log.info("orderId:{}" orderId);推荐
    

完善中。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值