5. JVM 性能优化

1. 内存溢出

内存溢出的方式:

  1. 栈溢出
  2. 堆溢出
  3. 方法区溢出
  4. 本级内存直接溢出

1.1 栈溢出

StackOverflowError:
方法自己调用自己,死递归导致的溢出。
OutOfMemoryError:
栈内存分配有限,每个线程占据一个内存空间,比如 1M,如果线程多了,会导致内存溢出。

1.2 堆溢出

1.3 方法区溢出

方法区垃圾回收效率很低,因此在加载动态语言、CGLIB、JSP、OSGI 时可能会内存溢出。

1.4 本地直接内存溢出

限制了本地直接内存的大小,分配时超过了其大小。

2. 内存泄露

内存溢出是程序申请内存时,没有足够的内存空间。
内存泄露是程序在申请内存后,无法释放已申请的内存空间。就是本意是无用的对象,但是没有释放,垃圾回收器无法回收内存空间。

内存泄漏的几种原因:

  1. 长生命周期的对象持有短生命周期对象的引用
  2. 连接未关闭
  3. 变量作用域不合理
  4. 内部类持有外部类
  5. Hash值改变

3. MAT

-XX:+HeapDumpOnOutOfMemoryError

深堆(Shallow Heap):分配一个对象所消耗的内存。
浅堆(Retained Heap):分配一个对象,在垃圾回收时真实可回收的内存大小。

在这里插入图片描述
Incoming:这个对象引用了谁。
Outgoing:谁引用了这个对象。

4. JDK 为我们提供的工具

在这里插入图片描述
jps -mlv
jstat -gc <pid>
jinfo -flags <pid>、jinfo -flag +PrintGCDetails 操作参数

可视化工具在使用时需要在远端程序中添加:
-Djava.rmi.server.hostname=…… -Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8888
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

5. JVM 调优

JVM 调优的本质是调整垃圾回收的频次,提升系统的稳定性,而不是提升性能。

影响一个系统性能的方方面面:
在这里插入图片描述

5.1 调优原则

  1. 大多数的 java 应用不需要 GC 调优。
  2. 大部分需要 GC 调优的,不是参数问题,而是代码问题。
  3. 在实际项目中,分析 GC 情况优化代码比调整 GC 参数要重要。
  4. GC 调优是最后的手段。

5.2 GC 调优目的

  1. GC 的时间足够小
    参考性指标:Minor GC 执行时间不到 50ms,Full GC 执行时间不到 1s。
  2. GC 的次数足够小
    参考性指标:Minor GC 执行不频繁,大于 10s 一次,Full GC 执行频率不算频繁,大于10min 1次。

5.3 调优步骤

  1. 监视 GC 状况
  2. 分析结果,判断是否需要优化
  3. 调整垃圾回收器类型、内存分配参数
  4. 不断分析、调整
  5. 全面应用参数

阅读 GC 日志:主要关注 Minor GC、Full GC 的回收效率(回收前大小、回收比较)、回收时间。

5.4 调优实战

  1. 项目启动 GC 优化
    启动后观察 Minor GC、Full GC 次数,优化参数达到调优目的。
  2. 项目运行 GC 优化
    切换不同垃圾回收器,JMeter 压测查看结果。

5.5 推荐策略

  1. 新生代大小选择
    响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制,在此种情况下,新生代收集发生的频率也是最小
    的,同时减少到达老年代的对象。
    吞吐量优先的应用:尽可能设大,可能到达 Gbit 的程度,因为对响应时间没有要求,垃圾收集可以并行进行,一般适合 8CPU 以上的应用。
    避免设置过小,当新生代设置过小时会导致:1.MinorGC 次数更加频繁;2.可能导致 MinorGC 对象直接进入老年代,如果此时老年代满了,会触发 FullGC。
  2. 老年代大小选择
    响应时间优先的应用:老年代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数:如果堆设置小了,可以会造成内存碎片,高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间。最优化的方案,一般需要参考以下数据获得:并发垃圾收集信息、持久代并发收集次数、传统 GC 信息、花在新生代和老年代回收上的时间比例。

6. 常用的性能评价指标

  1. 响应时间:一般关注平均响应时间
    在这里插入图片描述
  2. 并发数
    同一时刻,对服务器有实际交互的请求数。
  3. 吞吐量
    对单位时间内完成的工作量(请求)的量度。如:每分钟的数据库事务,每秒传送的文件千字节数,每分钟的 Web 服务器命中数。

7. 常用的性能优化手段

总原则:

  1. 避免过早优化
  2. 进行系统性能测试
  3. 寻找系统瓶颈,分而治之,逐步优化

优化分为:

  1. 前端优化
  2. 应用服务性能优化
  3. 存储性能优化

7.1 前端优化常用手段

  1. 浏览器/App:减少请求数;使用客户端缓冲;启用压缩;资源文件加载顺序;减少Cookie传输
  2. CDN加速
  3. 反向代理缓存
  4. WEB组件分离

7.2 应用服务性能优化手段

  1. 缓存
    网站性能优化第一定律:优先考虑使用缓存优化性能。
    缓存优化原则:缓存离用户越近越好。
    缓存的本质:数据读多改少的情况,将数据访问放到高效介质中。

  2. 集群

  3. 异步
    常见异步手段:Servlet 异步、多线程、消息队列。

  4. 程序
    代码级别、并发编程、算法、资源的复用(减少开销很大的系统资源的创建和销毁:单例模式、池化技术)、JVM。

7.3 存储性能优化手段

  1. 尽量使用SSD
  2. 定时清理数据或者按数据的性质分开存放
  3. 结果集处理

8. 虚拟机优化技术

栈上分配:对逃逸分析出来的对象有可能进行栈上分配。

牵涉到的 JVM 参数:

  1. -XX:+DoEscapeAnalysis:启用逃逸分析(默认打开)
  2. -XX:+EliminateAllocations:标量替换(默认打开)
  3. -XX:+UseTLAB:本地线程分配缓冲(默认打开)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值