Skip to main content

moregeek program

jvm问题分析调优经验_wx630f055ce23fc的博客-多极客编程

一、前言

​JVM​​ 性能优化步骤:

  1. 预估系统参数
  2. 压测后,调整JVM 参数
  3. 线上系统监控和优化
  4. 统一的JVM 参数模板

线上频繁 ​​Full GC​​ 的表现:

  • 机器CPU 负载过高
  • 频繁Full GC 报警
  • 系统无法处理请求或者处理过慢
频繁 ​​Full GC​​ 常见原因:
  1. 对象频繁进入老年代,频繁触发Full GC
    系统承载高并发请求,或处理数据量过大,导致Young GC 频繁,每次 Young GC 过后存活对象太多,内存分配不合理, Survivor 区域过小。
  2. 系统一次性加载过多数据进入内存,大对象直接入老年代,频繁触发Full GC
  3. 内存泄漏,对象无法回收,一直占用在老年代里,频繁触发Full GC
  4. ​MetaSpace​​ (永久代)加载类过多,触发 Full GC
  5. 代码中使用System.gc() ,触发 Full GC
针对以上 ​​Full GC​​ 常见的原因,对应的优化方式:
  1. ​jstat​​ 分析,合理分配内存,调大 Survivor 区域
  2. ​dump​​ 出内存快照,用 MAT 工具进行分析,代码上排查
  3. ​dump​​ 出内存快照,用 MAT 工具进行分析,代码上排查
  4. 若内存使用不多,还频繁触发Full GC ,那么优化加载的类
  5. 若内存使用不多,还频繁触发Full GC ,代码上排查,删除 System.gc()

一、案例一:高分配速率( ​​High Allocation Rate​​ )

分配速率( ​​Allocation rate​​ )表示单位时间内分配的内存量。

通常使用 ​​MB/sec​​ 作为单位。上一次垃圾收集之后, 与下一次 ​​GC​​ 开始之前的年轻代使用量, 两者的差值除以时间, 就是分配速率。分配速率过高就会严重影响程序的性能, 在 ​​JVM​​ 中可能会导致巨大的 ​​GC​​ 开销。

  • 正常系统: 分配速率较低 ~ 回收速率 -> 健康
  • 内存泄漏: 分配速率 持续大于 回收速率 ->OOM
  • 性能劣化: 分配速率较高 ~ 回收速率 -> 亚健康

JVM问题分析调优经验_内存泄漏

  1. ​JVM​​ 启动之后 291 ms, 共创建了 33,280 KB 的对象。第一次 Minor GC (小型 GC ) 完成后, 年轻代中还有 5,088 KB 的对象存活。
  2. 在启动之后 446 ms, 年轻代的使用量增加到 38,368 KB , 触发第二次GC , 完成后年轻代的使用量减少到 5,120 KB。
  3. 在启动之后 829 ms, 年轻代的使用量为 71,680 KB,GC 后变为 5,120 KB。

JVM问题分析调优经验_老年代_02

思考一个问题, 分配速率, 到底影响什么?

想一想, ​​new​​ 出来的对象, 在什么地方。

答案就是, ​​Eden​​ 。

假如我们增加 ​​Eden​​ , 会怎么样。考虑蓄水池效应。最终的效果是, 影响 ​​Minor GC​​ 的次数和时间, 进而影响吞吐量。

在某些情况下, 只要增加年轻代的大小, 即可降低分配速率过高所造成的影响。

增加年轻代空间并不会降低分配速率, 但是会减少 ​​GC​​ 的频率。如果每次 ​​GC​​ 后只有少量对象存活, ​​minor GC​​ 的暂停时间就不会明显增加。

二、案例二:过早提升( ​​Premature Promotion​​ )

提升速率( ​​promotion rate​​ )用于衡量单位时间内从年轻代提升到老年代的数据量。

一般使用 ​​MB/sec​​ 作为单位, 和分配速率类似。

​JVM​​ 会将长时间存活的对象从年轻代提升到老年代。根据分代假设, 可能存在一种情况, 老年代中不仅有存活时间长的对象, 也可能有存活时间短的对象。

这就是过早提升:  对象存活时间还不够长的时候就被提升到了老年代。

​major GC​​ 不是为频繁回收而设计的, 但 ​​major GC​​ 现在也要清理这些生命短暂的对象, 就会导致 ​​GC​​ 暂停时间过长。这会严重影响系统的吞吐量。

JVM问题分析调优经验_加载_03

​GC​​ 之前和之后的年轻代使用量以及堆内存使用量。

这样就可以通过差值算出老年代的使用量。

和分配速率一样, 提升速率也会影响 ​​GC​​ 暂停的频率。但分配速率主要影响 ​​minor GC​​ , 而提升速率则影响 ​​major GC​​ 的频率。

有大量的对象提升, 自然很快将老年代填满。老年代填充的越快, 则 ​​major GC​​ 事件的频率就会越高。

JVM问题分析调优经验_内存泄漏_04

一般来说过早提升的症状表现为以下形式:
  1. 短时间内频繁地执行full GC
  2. 每次full GC 后老年代的使用率都很低, 在 10-20% 或以下
  3. 提升速率接近于分配速率

要演示这种情况稍微有点麻烦, 所以我们使用特殊手段, 让对象提升到老年代的年龄比默认情况小很多。指定 ​​GC​​ 参数 ​​-Xmx24m -XX:NewSize=16m -XX:MaxTenuringThreshold=1​​ , 运行程序之后, 可以看到下面的 ​​GC​​ 日志:

JVM问题分析调优经验_老年代_05

解决这类问题, 需要让年轻代存放得下暂存的数据, 有两种简单的方法:
  1. 增加年轻代的大小, 设置JVM 启动参数, 类似这样: -Xmx64m -XX:NewSize=32m , 程序在执行时, Full GC 的次数自然会减少很多, 只会对 minor GC 的持续时间产生影响。
  2. 减少每次批处理的数量, 也能得到类似的结果。至于选用哪个方案, 要根据业务需求决定。在某些情况下, 业务逻辑不允许减少批处理的数量, 那就只能增加堆内存, 或者重新指定年轻代的大小。如果都不可行, 就只能优化数据结构, 减少内存消耗。

©著作权归作者所有:来自51CTO博客作者小二上酒8的原创作品,请联系作者获取转载授权,否则将追究法律责任

idea 使用 docker 插件,实现一键自动化部署_码农小宋的博客-多极客编程

一、 docker开启远程连接访问​首先我们要开启docker的远程连接访问。保证不是docker所在的服务器,也能够远程访问docker。Linux版的docker:修改 docker.service 文件,添加监听端口 -H tcp://0.0.0.0:2375vi /usr/lib/systemd/system/docker.service找到 ExecStart,在最后面添加 -H tcp

【java入门】十七 包机制_qq62fded605da02的博客-多极客编程

 当我们写的类越来越多的时候,看过去就很会眼花缭乱,而且找一个类的时候也不方便,并且类也不可以重名了。就像把所有的书都放在一个柜子里,想要去找某本书的时候就会很难找,参考图书馆,就会把图书按照分类放在不同的柜子里,这样不仅更整齐,找书也更快。Java也有类似的操作---包机制。包机制(package、import)包(package)相当于文件夹对于文件的作用。用于管理类、用于解决类的重名问题pa

sql 嵌套 n 层太长太难写怎么办?_江晓龙的博客-多极客编程

我们工作中写SQL处理数据是家常便饭,不管是应用内数据处理还是临时查询分析都可以用SQL完成,相对其他技术(如Java等高级语言)也更简单。不过,SQL的简单只限于简单需求,有些复杂计算场景SQL写起来却很难,嵌套N层以至于达到几百上千行,说SQL代码长度时通常不会以行计而是以KB计。这种情况并不少见,相信经常写SQL的小伙伴并不陌生。 为什么会出现这种情况呢?在http://c.raqsoft.

#yyds干货盘点# leetcode 热题 hot 100:两数相加_灰太狼_cxh的博客-多极客编程

题目:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。 示例 1:输入:l1 = [2,4,3], l2 = [5,6,4]输出:[7,0,8]解释:342 + 465 = 807.示例 2:输入:l1 = [0],

#yyds干货盘点# leetcode 热题 hot 100:两数之和_灰太狼_cxh的博客-多极客编程

题目:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。 示例 1:输入:nums = [2,7,11,15], target = 9输出:[0,1]解释:因为 nums[0] + nums[1]

apache druid数据查询套件详解计数、排名和分位数计算(送json-over-http和sql两种查询详解)_博学谷狂野架构师的博客-多极客编程

数据查询 今天这篇文章是之前两篇文章的续篇,所以,大家如果直接上来干,干不懂的话,就需要先去了解下之前的两篇文章,虽然跟上两篇文章关联性不是很强,但还是有一定关系。 提示到此结束! 欲看此文,必看如下两篇文章: 【超详细】Apache Durid从入门到安装详细教程 Apache Druid 数据摄取---本地数据和kafka流式数据 Druid支持JSON-over-HTTP和

python基础(二) | python的基本数据类型_wx62e40d60030b6的博客-多极客编程

第二章 基本数据类型⭐本专栏旨在对Python的基础语法进行详解,精炼地总结语法中的重点,详解难点,面向零基础及入门的学习者,通过专栏的学习可以熟练掌握python编程,同时为后续的数据分析,机器学习及深度学习的代码能力打下坚实的基础。🔥本文已收录于Python基础系列专栏: Python基础系列教程 欢迎订阅,持续更新。第一部分 数字类型1.1 数字类型的组成1.1.1 整数——不同进制的转

数据结构与算法(二)——顺序表_蓦然的博客-多极客编程

在程序中,经常需要将一组(通常是同为某个类型的)数据元素作为整体管理和使用,需要创建这种元素组,用变量记录它们,传进传出函数等。一组数据中包含的元素个数可能发生变化(可以增加或删除元素)。对于这种需求,最简单的解决方案便是将这样一组元素看成一个序列,用元素在序列里的位置和顺序,表示实际应用中的某种有意义的信息,或者表示数据之间的某种关系。这样的一组序列元素的组织形式,我们可以将其抽象为线性表。一个

idea 使用 docker 插件,实现一键自动化部署_码农小宋的博客-多极客编程

一、 docker开启远程连接访问​首先我们要开启docker的远程连接访问。保证不是docker所在的服务器,也能够远程访问docker。Linux版的docker:修改 docker.service 文件,添加监听端口 -H tcp://0.0.0.0:2375vi /usr/lib/systemd/system/docker.service找到 ExecStart,在最后面添加 -H tcp

python图像处理丨认识图像锐化和边缘提取的4个算子_华为云开发者社区的博客-多极客编程

摘要:图像锐化和边缘提取技术可以消除图像中的噪声,提取图像信息中用来表征图像的一些变量,为图像识别提供基础。本文分享自华为云社区《​​[Python图像处理] 十七.图像锐化与边缘检测之Roberts算子、Prewitt算子、Sobel算子和Laplacian算​​》,作者: eastmount 。由于收集图像数据的器件或传输数图像的通道的存在一些质量缺陷,文物图像时间久远,或者受一些其他外界因素

#yyds干货盘点# leetcode 热题 hot 100:两数相加_灰太狼_cxh的博客-多极客编程

题目:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。 示例 1:输入:l1 = [2,4,3], l2 = [5,6,4]输出:[7,0,8]解释:342 + 465 = 807.示例 2:输入:l1 = [0],

超简单的python教程系列——第9篇:列表解析和生成器表达式_freestu的博客-多极客编程

如果我必须选择 Python 一个最喜欢的特性,那就必须是列表解析,毫无疑问。在我看来,它们封装了“Pythonic”代码的精髓……这很讽刺,因为它们实际上是从 Haskell 借鉴来的。我很兴奋能找到他们。这是我几周前计划写的文章,但我意识到理解迭代器对于真正了解列表解析及其潜力至关重要。如果你还没有阅读前两篇关于《循环和迭代器》和《迭代工具》的文章,那么你现在可以回去看看。列表解析与生成器表达