字节跳动应用性能监控帮助客户Java OOM崩溃率下降80%
本文将会从Java内存基础开始,详细介绍“基于Hprof内存快照的线上Java OOM 归因方案”的底层原理与技术细节,欢迎接入MARS-APMPlus 应用性能监控使用。
一、前言
二、Java 内存基础
2.1 Java 内存优化的重要性
2.2 为什么会Java OOM崩溃
Java Out Of Memory
,字面意思是说Java 虚拟机的内存用完。Java有一个相关的异常类 java.lang.OutOfMemoryError
,官方有如下说明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.
- Java虚拟机都有哪些内存区域
- 垃圾回收器是如何工作回收内存的
- 每个对象占据多大的内存空间
- Java 虚拟机当前的内存空间状态以及OOM是如何发生的
2.1.1 Java虚拟机的内存区域
名称 | 说明 | 是否线程间共享 |
PC Register | 称为程序计数器, 看作是当前线程所执行的字节码的行号指示器 | 否 |
JVM Stack | 也称为虚拟机栈,记录每个栈帧(Frame)中的局部变量、方法返回地址等 | 否 |
Native Method Stack | 本地 (原生) 方法栈,是调用操作系统原生本地方法时,所需要的内存区域 | 否 |
Heap | 堆内存区,也是 GC 垃圾回收的主要场所,用于存放类的实例对象 | 是 |
Method Area | 方法区,主要存放类结构、类成员定义,static 静态成员等 | 是 |
Runtime Constant Pool | 运行时常量池,比如:字符串等 | 是 |
2.1.2 垃圾回收器是如何工作回收内存的
2.1.3 对象占据多大的内存空间
Dominator Tree
支配树, Dominator Tree
有以下几个定义: - 对象X
Dominator
(支配)对象Y,当且仅当在对象树中所有到达Y的路径都必须经过X - 对象Y的直接
Dominator
,是指在对象引用关系中距离Y最近的Dominator
Dominator tree
利用对象引用关系构建出来
Dominator tree
的对应关系如下: Dominator tree
时,会A、B、C三个是平级的。 Dominator Tree
能帮助我们快速的发现占用内存最大的块,也能帮我们分析对象之间的依赖关系。 S
hallow
Size
:对象本身占用内存的大小。也就是对象头加成员变量(不是成员变量的值)的总和,如一个引用占用32或64bit,一个integer占4bytes,Long占8bytes等。常规对象(非数组)的Shallow Size 由其成员变量的数量和类型决定,数组的 Shallow Size 由数组元素的类型(对象类型、基本类型)和数组长度决定。例如E的Shallow Size,只是自身大小和他引用的G没有关系。R
etained
Size
:对象被垃圾回收器回收后能被GC从内存中移除的所有对象内存大小之和。相对于Shallow Size,Retained Size可以更精确的反映一个对象实际占用的大小(若该对象释放,Retained Size都可以被释放)。例如E到C的引用链断开后,会释放E、G这2个对象。这2个对象的所占内存之和就是E的Retained Size。
2.1.4 Java OOM的发生
java.lang.OutOfMemoryError: Failed to allocate a 65552 byte allocation with 23992 free bytes and 23KB until OOM, max allowed footprint 536870912, growth limit 536870912
OutOfMemoryError
抛出的地方在系统源码文件/runtime/gc/heap.cc //方法 void Heap::ThrowOutOfMemoryError(Thread* self, size_t byte_count, AllocatorType allocator_type) //异常信息 oss << "Failed to allocate a " << byte_count << " byte allocation with " << total_bytes_free << " free bytes and " << PrettySize(GetFreeMemoryUntilOOME()) << " until OOM," << " target footprint " << target_footprint_.load(std::memory_order_relaxed) << ", growth limit " << growth_limit_;
OutOfMemoryError
异常。 - Runtime.getRuntime().maxMemory() : 当前虚拟机实例的内存使用上限
- Runtime.getRuntime().totalMemory() : 当前已经申请的内存,包括已经使用的和还没有使用的
- Runtime.getRuntime().freeMemory() : totalMemory中已经申请但是尚未使用的部分
- used=totalMemory() - freeMemory(): 已经申请并且正在使用的部分
- totalFree=maxMemory()-used: Java虚拟机还可以使用的部分
OutOfMemoryError
异常。 2.3 Java内存相关工具
工具名称 | 介绍 | 优点 | 缺点 |
MAT | The Eclipse Memory Analyzer is a fast and feature-rich that helps you find memory leaks and reduce memory consumption. | 分析功能强大 | 线下分析,需要自己采集Hprof文件 |
LeakCanary | LeakCanary is a memory leak detection library for Android. | 可以接入App自动分析 | 线下分析,主要分析内存泄露 |
Android Studio Memory Profiler | 可帮助用户识别可能会导致应用卡顿、冻结甚至崩溃的内存泄露和内存抖动 | 可以动态内存监控,也可以静态内存分析 | 线下分析,需要App debug模式 |
- 都是线下工具,线下复现Java OOM问题困难
- 自动化程度低,只能手动操作分析内存问题
- 都是单点工具,只能分析单个hprof文件,没法聚合找到核心问题
三、Java OOM归因方案
- 高度还原场景:可以拿到Java OOM时候的场景内存数据
- 自动化分析:可以自动化进行内存数据分析
- 聚合找到核心问题:可以根据问题特征聚合发现核心问题
- 隐私安全:因为是线上监控,所以需要满足用户隐私安全的要求
3.1 Hprof基础知识
3.1.1 Hprof介绍
3.1.2 Hprof结构
3.1.3 Hprof文件使用
3.2 方案概要
- 端SDK:负责Hprof文件的采集、裁剪、压缩及上报等
- 服务端:Hprof文件存储、还原、自动分析、结果Retrace、issue聚合,自动分配等
- 前端:问题展示包括内存泄露、大对象、类大对象等
3.3 方案原理
3.2.1 内存文件端上dump
- OOM之后还要再进行 dump 操作确实会容易dump失败。
- OOM时候App崩溃不可用,dump操作会在崩溃时候导致卡顿。
3.2.2 内存文件的裁剪和还原
- 规避隐私风险:Hprof保存了执行Dump时刻Java堆上所有的内存信息,包括存在内存中的账户信息等,这些敏感信息必须裁剪掉。
- 减小文件大小:因为堆内存不足而OOM的时候获到的Hprof文件,约等于设备单进程最大可用内存,一般文件比较大有几百M,大文件上传浪费用户流量、带宽以及导致上报成功率降低。
- 根据Hprof文件的格式进行分析,分析我们不需要关注的数据块
- 将文件映射进内存,根据文件格式找到想要裁剪的数据块
- 再次写入文件的时候不要写第2步找到的数据块
- 这样产生的Hprof文件就是裁剪后的
3.2.3 内存文件的自动化解析
- 内存泄露
- 大对象
- 小对象
3.2.3.1 内存泄露
private boolean mDestroyed; final void performDestroy() { mDestroyed = true; xxx }
3.2.3.2 大对象
if (object != null && object.getRetainedHeapSize() > MINIMAL){ // 算作大对象 }
3.2.3.3 类大对象
3.2.4 聚合和Retrace
3.2.4.1 聚合
3.2.4.2 Retrace
3.2.5 自动分配
当前在火山引擎的MARS-APMPlus 应用性能监控无法获取用户的仓库解析Class Owner,暂时无法自动分配。
3.2.6 总结
四、优化效果
4.1 内部效果
4.2 外部效果
五、接入使用
🔥 火山引擎 APMPlus 应用性能监控是火山引擎应用开发套件 MARS 下的性能监控产品。我们通过先进的数据采集与监控技术,为企业提供全链路的应用性能监控服务,助力企业提升异常问题排查与解决的效率。目前产品正在免费公测阶段,👉 戳这里了解更多产品信息。欢迎大家进行试用!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
使用虚拟机在CentOS上安装部署数据库使用
镜像下载、域名解析、时间同步请点击 阿里云开源镜像站 本节描述使用数据库的基本操作。通过此节您可以完成创建数据库、创建表及向表中插入数据和查询表中数据等操作。 2.1 前提条件 ●openGauss正常运行。 ●由于本实验是对openGauss数据库的基本使用,需要掌握openGauss数据库的基本操作和SQL语法,openGauss数据库支持SQL2003标准语法,数据库基本操作参见附录二。 2.2 操作步骤 步骤 1以操作系统用户omm登录数据库主节点。 [root@ecs-c9bf script]# su - omm 若不确定数据库主节点部署在哪台服务器,请确认连接信息。 步骤 2启动服务。 启动服务命令: [omm@ecs-c9bf ~]$ gs_om -t start Starting cluster. ========================================= ========================================= Successfully started. 步骤 3连接数据库。 [omm@ecs-c9bf ~]$ gsq...
- 下一篇
一键AI着色,黑白老照片画面瞬间鲜活
很多老照片或者电影受时代技术所限制,只能以黑白形式保存;经过编辑后的黑白视频和图片早已丢失彩色原图,这对于保存者来说都十分遗憾。如何能将单一乏味、陈旧斑驳的黑白照片变成鲜活亮丽的彩色照片,从照片中重新获取更多的特征细节,让观看者产生更强的代入感和情感共鸣呢? 华为视频编辑服务(Video Editor Kit)全新上线的“AI着色”能力,为开发者提供了黑白一键着色的解决方案。应用在集成视频编辑服务“AI着色”能力后,用户只需要上传一张黑白照片或者一段黑白视频,即可获得鲜活多彩的彩色照片或视频。 操作简单,效果也很不错! 快来看下集成步骤吧! 集成代码 1 开发准备 详细准备步骤可参考华为开发者联盟官网: https://developer.huawei.com/consumer/cn/doc/development/Media-Guides/config-agc-0000001101108580?ha_source=hms1 2 编辑工程集成 2.1 设置应用的鉴权信息 可以通过api_key或者Access Token来设置应用鉴权信息。 通过setAccessToken方法设置Ac...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8编译安装MySQL8.0.19
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7