跨境互联网 跨境互联网
首页
  • AI 工具

    • 绘图提示词工具 (opens new window)
    • ChatGPT 指令 (opens new window)
  • ChatGPT

    • ChatGP T介绍
    • ChatGPT API 中文开发手册
    • ChatGPT 中文调教指南
    • ChatGPT 开源项目
  • Midjourney

    • Midjourney 文档
  • Stable Diffusion

    • Stable Diffusion 文档
  • 其他

    • AIGC 热门文章
    • 账号合租 (opens new window)
    • 有趣的网站
  • Vue

    • Vue3前置
  • JAVA基础

    • Stream
    • Git
    • Maven
    • 常用第三方类库
    • 性能调优工具
    • UML系统建模
    • 领域驱动设计
    • 敏捷开发
    • Java 测试
    • 代码规范及工具
    • Groovy 编程
  • 并发编程&多线程

    • 并发编程
    • 高性能队列 Disruptor
    • 多线程并发在电商系统下的应用
  • 其他

    • 面试题
  • 消息中间中间件

    • Kafka
    • RabbitMQ
    • RocketMQ
  • 任务调度

    • Quartz
    • XXL-Job
    • Elastic-Job
  • 源码解析

    • Mybatis 高级使用
    • Mybatis 源码剖析
    • Mybatis-Plus
    • Spring Data JPA
    • Spring 高级使用
    • Spring 源码剖析
    • SpringBoot 高级使用
    • SpringBoot 源码剖析
    • Jdk 解析
    • Tomcat 架构设计&源码剖析
    • Tomcat Web应用服务器
    • Zookeeper 高级
    • Netty
  • 微服务框架

    • 分布式原理
    • 分布式集群架构场景化解决方案
    • Dubbo 高级使用
    • Dubbo 核心源码剖析
    • Spring Cloud Gateway
    • Nacos 实战应用
    • Sentinel 实战应用
    • Seata 分布式事务
  • 数据结构和算法的深入应用
  • 存储

    • 图和Neo4j
    • MongoDB
    • TiDB
    • MySQL 优化
    • MySQL 平滑扩容实战
    • MySQL 海量数据存储与优化
    • Elasticsearch
  • 缓存

    • Redis
    • Aerospike
    • Guava Cache
    • Tair
  • 文件存储

    • 阿里云 OSS 云存储
    • FastDF 文件存储
  • 基础

    • Linux 使用
    • Nginx 使用与配置
    • OpenResty 使用
    • LVS+Keepalived 高可用部署
    • Jekins
  • 容器技术

    • Docker
    • K8S
    • K8S
  • 01.全链路(APM)
  • 02.电商终极搜索解决方案
  • 03.电商亿级数据库设计
  • 04.大屏实时计算
  • 05.分库分表的深入实战
  • 06.多维系统下单点登录
  • 07.多服务之间分布式事务
  • 08.业务幂等性技术架构体系
  • 09.高并发下的12306优化
  • 10.每秒100W请求的秒杀架构体系
  • 11.集中化日志管理平台的应用
  • 12.数据中台配置中心
  • 13.每天千万级订单的生成背后痛点及技术突破
  • 14.红包雨的架构设计及源码实现
  • 人工智能

    • Python 笔记
    • Python 工具库
    • 人工智能(AI) 笔记
    • 人工智能(AI) 项目笔记
  • 大数据

    • Flink流处理框架
  • 加密区

    • 机器学习(ML) (opens new window)
    • 深度学习(DL) (opens new window)
    • 自然语言处理(NLP) (opens new window)
AI 导航 (opens new window)

Revin

首页
  • AI 工具

    • 绘图提示词工具 (opens new window)
    • ChatGPT 指令 (opens new window)
  • ChatGPT

    • ChatGP T介绍
    • ChatGPT API 中文开发手册
    • ChatGPT 中文调教指南
    • ChatGPT 开源项目
  • Midjourney

    • Midjourney 文档
  • Stable Diffusion

    • Stable Diffusion 文档
  • 其他

    • AIGC 热门文章
    • 账号合租 (opens new window)
    • 有趣的网站
  • Vue

    • Vue3前置
  • JAVA基础

    • Stream
    • Git
    • Maven
    • 常用第三方类库
    • 性能调优工具
    • UML系统建模
    • 领域驱动设计
    • 敏捷开发
    • Java 测试
    • 代码规范及工具
    • Groovy 编程
  • 并发编程&多线程

    • 并发编程
    • 高性能队列 Disruptor
    • 多线程并发在电商系统下的应用
  • 其他

    • 面试题
  • 消息中间中间件

    • Kafka
    • RabbitMQ
    • RocketMQ
  • 任务调度

    • Quartz
    • XXL-Job
    • Elastic-Job
  • 源码解析

    • Mybatis 高级使用
    • Mybatis 源码剖析
    • Mybatis-Plus
    • Spring Data JPA
    • Spring 高级使用
    • Spring 源码剖析
    • SpringBoot 高级使用
    • SpringBoot 源码剖析
    • Jdk 解析
    • Tomcat 架构设计&源码剖析
    • Tomcat Web应用服务器
    • Zookeeper 高级
    • Netty
  • 微服务框架

    • 分布式原理
    • 分布式集群架构场景化解决方案
    • Dubbo 高级使用
    • Dubbo 核心源码剖析
    • Spring Cloud Gateway
    • Nacos 实战应用
    • Sentinel 实战应用
    • Seata 分布式事务
  • 数据结构和算法的深入应用
  • 存储

    • 图和Neo4j
    • MongoDB
    • TiDB
    • MySQL 优化
    • MySQL 平滑扩容实战
    • MySQL 海量数据存储与优化
    • Elasticsearch
  • 缓存

    • Redis
    • Aerospike
    • Guava Cache
    • Tair
  • 文件存储

    • 阿里云 OSS 云存储
    • FastDF 文件存储
  • 基础

    • Linux 使用
    • Nginx 使用与配置
    • OpenResty 使用
    • LVS+Keepalived 高可用部署
    • Jekins
  • 容器技术

    • Docker
    • K8S
    • K8S
  • 01.全链路(APM)
  • 02.电商终极搜索解决方案
  • 03.电商亿级数据库设计
  • 04.大屏实时计算
  • 05.分库分表的深入实战
  • 06.多维系统下单点登录
  • 07.多服务之间分布式事务
  • 08.业务幂等性技术架构体系
  • 09.高并发下的12306优化
  • 10.每秒100W请求的秒杀架构体系
  • 11.集中化日志管理平台的应用
  • 12.数据中台配置中心
  • 13.每天千万级订单的生成背后痛点及技术突破
  • 14.红包雨的架构设计及源码实现
  • 人工智能

    • Python 笔记
    • Python 工具库
    • 人工智能(AI) 笔记
    • 人工智能(AI) 项目笔记
  • 大数据

    • Flink流处理框架
  • 加密区

    • 机器学习(ML) (opens new window)
    • 深度学习(DL) (opens new window)
    • 自然语言处理(NLP) (opens new window)
AI 导航 (opens new window)
  • 基础

  • 设计模式

  • 并发编程

  • JVM与性能调优

    • JVM

      • 虚拟机概述
      • 类文件结构
      • 运行数据区
      • 类加载
      • 对象创建
      • 对象的销毁
      • 调优实战
        • 7.1 环境
        • 7.2 初始状态
          • 7.2.1 参数
          • 7.2.2 执行日志
          • 7.2.3 日志分析
        • 7.3 初步调优
          • 7.3.1 参数
          • 7.3.2 二次分析
        • 7.4 二次调优
          • 7.4.1 参数
          • 7.4.2 日志分析
        • 7.5 小结
    • JVM调优

    • 性能调优工具
  • 字节码增强技术

  • java
  • JVM与性能调优
  • JVM
Revin
2023-08-03
目录

调优实战

# 7.1 环境

  • 我们依然使用上面收集器章节相同的案例,这次针对内存来做详细分析。
  • 使用企业里主流的jdk8运行,其他jdk版本参数可能略有不同。
  • jdk自带的分析命令和工具给大家准备了扩展资料
  • 这里我们使用在线、简洁、高效的图形化分析工具: http://gceasy.io
  • gc日志参数:
-XX:+PrintGC 输出GC日志
-XX:+PrintGCDetails 输出GC的详细日志
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
-Xloggc:gc.log   jdk8日志文件的输出


-Xlog:gc*:gc.log  jdk11日志输出方式略有不同
1
2
3
4
5
6
7
8
9

# 7.2 初始状态

# 7.2.1 参数

-Xmx32m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:gc.log
1

image-20210408162538333

# 7.2.2 执行日志

运行一段时间后,在项目的目录下会看到gc.log

image-20210408163439858

# 7.2.3 日志分析

打开 gceasy 的主页,上传后点击 Analyze 即可看到分析结果

image-20210408163653183

1)整体内存概况

young与old全部吃满,均明显不足,需要调大,meta闲置,可以缩减

image-20210408163949306

2)整体时间情况

收集时间绝大多数在10ms以内,说明收集的速度还可以,但是回收次数明显偏多,整体吞吐量94

image-20210408164152924

3)回收前后的heap明显抖动频繁,整体偏高

image-20210408172308650

4)GC间隔时间长的点,发生大量FullGC

image-20210408172408015

5)大批量空间的有效释放在FullGC上

image-20210408172501063

6)回收释放情况

年轻代和年老代回收效果一般,回收前后的两条线甚至发生交叉,应该偏离较远才说明有明显内存下降

Metaspace比较稳定

image-20210408172628499

7)A&P:对象从年轻代晋升到老年代的情况

频繁晋升,跨代移动,说明年轻代不够用,老年代一旦堆积,极容易引发fullGC

image-20210408173001294

8)GC次数及时间统计

发生591次GC,里面竟然有45是FullGC,不可容忍!

总GC耗时,2.820s,FullGC占了将近一半

image-20210408173408882

9)GC停顿情况

总耗时、平均每次GC耗时 4.77ms

image-20210408173756291

10)GC被触发的原因

常规达到阈值垃圾回收45次。

内存分配失败引发回收,这个会影响正常业务执行。

image-20210408173912968

# 7.3 初步调优

# 7.3.1 参数

分析上面的情况,明显年轻代老年代内存均严重不足,那么最简单粗暴的方式,我们加大内存

-Xms256m -Xmx256m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:gc.log
1

# 7.3.2 二次分析

重复上面的步骤,新开一个浏览器页签,方便对比分析日志,重点关注几个点:

1)总内存够用了,但是年轻代依然被吃爆。年老代闲置。

image-20210408180257479

2)吞吐量上升,耗时特别长的gc分部区间明显减少,甚至消失

image-20210408180340673

3)gc前后的空间曲线对比明显

image-20210408180429177

4)FullGC消失!

image-20210408180505228

5)GC大批量的内存释放发生在了年轻代

image-20210408180546815

6)年轻代的回收前后两条曲线不再交叉,被明显剥离

image-20210408180621878

7)年老代表示情绪稳定

image-20210408180647712

8)年轻到老年代的晋升明显减少

image-20210408180717968

9)FullGC完全消失,总GC次数明显减少到49,总停顿时间从上次的2.8s降低到0.3s

image-20210408180822553

10)晋升的对象明显减少,创建速度提升

image-20210408181044095

11)不再发生内存分配失败造成gc的现象

image-20210408181203637

# 7.4 二次调优

# 7.4.1 参数

结合上次调优,我们发现,年轻代依然不够用,年老代闲置,对象还是会频繁从年轻代晋升到年老代。

结合我们的业务场景,大批量对象在请求后会被释放,属于短生命周期。包括我们现实中从数据库请求发送到网页后对象就完成了实名,属于同类场景。

所以,加大年轻代比例!

-Xms256m -Xmx256m -XX:NewSize=250m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:gc.log
1

# 7.4.2 日志分析

同样是256的内存,我们再次跑出日志分析看看差异

1)年轻代已基本够用,很少有对象再跑到老年代

image-20210408182302407

2)吞吐量进一步上升

image-20210408182416738

思考一下,那为什么pause的平均时间还变长了呢???

答:次数变少了,单次需要收集的对象多了,所以肯定要占时间,我们接着往下看总耗时!

3)堆回收空间变化明显

image-20210408185109798

4)gc次数明显下降到8次,总时间进一步降低到80ms

image-20210408185136455

# 7.5 小结

  • 机器主要用来跑java服务的话,一般是需要调优的。因为默认堆最大只占物理内存的1/4
  • jvm的调优没有标准可言,不同业务场景的内存占用和增长情况不同。调整需要根据结果一步步来,直到最优。
  • 调优工具很多,gceasy属于简单直观的ui操作,jvm自带工具大多是命令行且功能较少,在扩展资料里。
  • parallel是jdk8下的默认收集器,切换不同收集器后的调试与上面过程一致,感兴趣的同学可以逐个尝试。
上次更新: 2025/04/03, 11:07:08
对象的销毁
前言

← 对象的销毁 前言→

最近更新
01
tailwindcss
03-26
02
PaddleSpeech
02-18
03
whisper
02-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 跨境互联网 | 豫ICP备14016603号-5 | 豫公网安备41090002410995号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式