当前位置: 首页 > news >正文

11.3JVM调优

JVM 内存参数基础

1. 堆内存参数
# 设置堆的初始和最大大小(推荐初始值和最大值一致,避免动态扩容)
java -Xms512m -Xmx512m YourMainClass# 设置新生代大小(新生代 = Eden + 2个Survivor区)
java -Xmn256m YourMainClass# 设置新生代与老年代的比例(默认1:2,-XX:NewRatio=2 表示新生代占1/3)
java -XX:NewRatio=2 YourMainClass# 设置Eden区与Survivor区的比例(默认8:1:1,-XX:SurvivorRatio=8 表示Eden:Survivor=8:1)
java -XX:SurvivorRatio=8 YourMainClass
2. 元空间参数(JDK 8+)
# 设置元空间初始和最大大小(替代JDK 7的永久代 -XX:MaxPermSize)
java -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m YourMainClass
3. 栈内存参数
# 设置每个线程的栈大小(默认1M,减小可增加并发线程数)
java -Xss512k YourMainClass

垃圾回收器选择与优化

JVM 提供多种 GC 策略,需根据应用特点选择:

1. 串行 GC(Serial GC)
# 单线程GC,适合小内存、单核环境
java -XX:+UseSerialGC YourMainClass
  • 适用场景:单线程环境,尤其是客户端应用或小型应用程序。
  • 它通过暂停所有应用程序线程来进行垃圾回收,因此对于需要高响应性的服务端应用来说不是最佳选择。
  • 特点:简单、适合资源受限的环境。
2. 并行 GC(Parallel GC)

Java 8中,默认使用的垃圾回收器是Parallel GC

# 多线程回收,关注吞吐量(CPU利用率)
java -XX:+UseParallelGC YourMainClass# 设置并行GC线程数
java -XX:ParallelGCThreads=4 YourMainClass
  • 适用场景:计算密集型、对响应时间要求不高的服务。
  • 在Java 8中,默认使用的垃圾回收器是Parallel GC,也称为吞吐量收集器(Throughput Collector)。Parallel GC使用多线程进行年轻代和老年代的垃圾回收,旨在最大化应用程序的吞吐量。这意味着它会尝试在最短的时间内完成垃圾回收过程,但为此可能会导致较长时间的“stop-the-world”暂停,这对于某些对延迟敏感的应用来说可能不是最佳选择。
  • 使用多线程进行垃圾回收,旨在最大化应用程序的吞吐量。
  • 虽然可以显著减少GC时间,但因为它是“stop-the-world”的,所以在延迟敏感的应用中可能不适用。
  • 特点:高效利用多核处理器,提高吞吐量。
3. CMS GC(Concurrent Mark Sweep)
# 低延迟GC,关注响应时间
java -XX:+UseConcMarkSweepGC YourMainClass# 设置CMS线程数
java -XX:ConcGCThreads=2 YourMainClass# 设置老年代使用CMS的触发百分比(默认92%)
java -XX:CMSInitiatingOccupancyFraction=70 YourMainClass
  • 适用场景:Web 应用、API 服务(需快速响应)。
  • 设计目的是为了最小化停顿时间,适合于需要快速响应的应用程序。
  • CMS尝试与应用程序线程并发地执行大部分垃圾收集工作,但在某些阶段仍需要暂停应用程序线程。
  • 特点:降低GC导致的停顿时间,但可能会导致更高的CPU使用率。
4. G1 GC(Garbage First)

自Java 9以来成为默认的垃圾回收器

# JDK 9+默认GC,分代不分区,兼顾吞吐量和低延迟
java -XX:+UseG1GC YourMainClass# 设置最大停顿时间目标(毫秒)
java -XX:MaxGCPauseMillis=200 YourMainClass# 设置堆区域大小(默认2048个区域,每区域1-32MB)
java -XX:G1HeapRegionSize=4m YourMainClass
  • 适用场景:大内存(>4GB)、多核心服务器。
  • 自Java 9以来成为默认的垃圾回收器,在之后的版本中继续得到改进。
  • G1是一个服务器风格的垃圾收集器,适用于具有大堆内存或多核处理器的系统。
  • 它将堆划分为多个区域,并优先处理包含最多可回收空间的区域,从而提供更可预测的停顿时间。
  • 特点:平衡了低延迟和高吞吐量的需求,提供了较好的停顿时间控制。
5. ZGC(JDK 11+)
# 超大型堆(TB级)、极低延迟(<10ms)
java -XX:+UseZGC YourMainClass# 设置ZGC线程数
java -XX:ConcGCThreads=4 YourMainClass
  • 适用场景:需要处理 TB 级数据的应用(如大数据、金融交易系统)。
  • ZGC是Oracle为解决大型堆上的低延迟需求而开发的新一代垃圾收集器。
  • 它的设计目标是能够在TB级别的堆上运行,同时保持非常低的暂停时间(不超过10毫秒),并且这些暂停时间不会随着堆大小的增长而增加。
  • 特点:极低的暂停时间,适合对延迟要求严格的大型应用。

6. Shenandoah GC

  • 类似于ZGC,也是设计来解决低延迟问题,由Red Hat贡献给OpenJDK项目。
  • 它能够在一个非常大的堆上运作,并且停顿时间不依赖于堆的大小。
  • 特点:低延迟,适合长时间运行的服务端应用
  • 你需要确保你的JDK版本支持它。如果你使用的是支持Shenandoah的JDK版本(如OpenJDK 12或更新版本),可以通过以下JVM参数启用Shenandoah GC:

    -XX:+UseShenandoahGC

    例如,启动Java应用程序并指定使用Shenandoah GC,你可以这样设置:

    java -XX:+UseShenandoahGC MyApp

    请注意,由于Shenandoah GC在某些JDK版本中可能仍然被视为实验性特性,因此其性能和稳定性可能会有所变化。如果你正在使用Oracle JDK,并希望利用Shenandoah GC,但发现默认未包含此功能,考虑切换到提供Shenandoah支持的OpenJDK构建版,如AdoptOpenJDK(现在是Eclipse Temurin),它们可能对Shenandoah有更好的支持。

GC 优化实战策略

1. 新生代大小优化
  • 策略
    • 新生代过小 → Minor GC 频繁。
    • 新生代过大 → 单次 Minor GC 耗时增加,可能导致 FULL GC。
  • 经验值
    • 对于短生命周期对象为主的应用(如 Web 服务),新生代占堆的 1/3~1/2。
    • 对于长生命周期对象为主的应用(如缓存服务),适当减小新生代。
  • 大对象直接进入老年代

    java -XX:PretenureSizeThreshold=1048576 YourMainClass # 超过1MB的对象直接进入老年代
    
2. 对象晋升年龄调整
java -XX:MaxTenuringThreshold=15 YourMainClass  
# 默认15次Minor GC后晋升到老年代
  • 对于短生命周期对象,可降低阈值(如-XX:MaxTenuringThreshold=3)。
 3.元空间溢出(java.lang.OutOfMemoryError: Metaspace)
  • 原因
    • 动态生成大量类(如反射、CGLIB 代理)。
    • 元空间大小设置过小。
  • 解决
    java -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m YourMainClass
    
4. 栈溢出(java.lang.StackOverflowError)
  • 原因
    • 方法调用栈过深(如递归无终止条件)。
    • 栈空间设置过小。
  • 解决
    # 增加栈大小
    java -Xss2m YourMainClass# 修复递归逻辑,添加终止条件
    

JVM 监控与分析工具

1. 命令行工具
  • jstat:查看 GC 统计信息
    jstat -gc 1234 1000  # 每1秒打印一次进程ID为1234的GC信息
    
  • jmap:生成堆转储文件
    jmap -dump:format=b,file=heapdump.hprof 1234  # 生成进程1234的堆转储文件
    
  • jstack:打印线程栈信息(排查死锁)
    jstack 1234 > threaddump.txt  # 导出进程1234的线程栈
    
2. 可视化工具
  • VisualVM:集成多种监控功能(内存、线程、CPU 等)
    jvisualvm  # 启动VisualVM
    
  • MAT(Memory Analyzer Tool):分析堆转储文件,定位内存泄漏
    • 打开heapdump.hprof文件,查看大对象、对象引用链。
  • G1GC 日志分析
    java -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log YourMainClass
    

    使用工具(如GCViewer)分析 GC 日志。

JVM 内存调优最佳实践

  1. 优先通过监控工具定位问题

    • 分析 GC 日志 → 确定瓶颈(Minor GC 频繁?FULL GC 耗时过长?)。
    • 使用堆转储文件查找内存泄漏。
  2. 从小规模测试开始

    • 在测试环境验证参数配置,逐步调整至生产环境。
  3. 避免过度调优

    • 现代 GC(如 G1、ZGC)已针对大多数场景自动优化,仅在必要时手动调整。
  4. 结合代码优化

    • 减少创建大对象,及时释放资源(如try-with-resources)。
    • 使用对象池(如 Apache Commons Pool)复用对象。

http://www.xdnf.cn/news/747739.html

相关文章:

  • 零基础SEO优化操作全解析
  • 2006-2024年 上市公司-企业战略联盟数据-社科经管实证数据
  • 打开NRODIC SDK编译不过怎么处理,keil与segger studio
  • CppCon 2014 学习:Modern Template Metaprogramming A Compendium
  • 【LLM相关知识点】关于LangChain框架学习简单整理(三)
  • C++17新特性 Lambda表达式
  • 神奇的平方和运算
  • 法规解读——GB/T 前向碰撞预警功能FCW
  • kafka学习笔记(三、消费者Consumer使用教程——配置参数大全及性能调优)
  • 数据库核心技术深度剖析:事务、索引、锁与SQL优化实战指南(第三节)----从全局锁到行锁的全面总结
  • ShenNiusModularity项目源码学习(31:ShenNius.Admin.Mvc项目分析-16)
  • 【Doris基础】Apache Doris中的Segment详解:存储与查询的核心组件
  • python分配方案数 2023年信息素养大赛复赛/决赛真题 小学组/初中组 python编程挑战赛 真题详细解析
  • VLAN的作用和原理
  • 命令行式本地与服务器互传文件
  • python:在 PyMOL 中如何查看和使用内置示例文件?
  • MySQL存储架构深度解析:从引擎选型到云原生实践(2025最新版)
  • 【系统配置与部署类】docker的深度配置和应用
  • 5G 网络中的双向认证机制解析
  • 跟单业务和量化交易业务所涉及到的设计模式
  • CP2K 软件介绍与使用指南
  • 34、请求处理-【源码分析】-Model、Map原理
  • MySQL访问控制与账号管理:原理、技术与最佳实践
  • switch-case判断
  • 【PostgreSQL 02】PostgreSQL数据类型革命:JSON、数组与地理信息让你的应用飞起来
  • 若依框架定制化服务搭建
  • 开源是什么?我们为什么要开源?
  • gtsam正确的安装姿势
  • 每日八股文5.31
  • Windows上用FFmpeg推流及拉流的流程概览