使用tsf分析服务器的内存使用情况【经典版】

目录

[一 背景说以及总结](#一 背景说以及总结)

[1.1 tsf显示的内存概述](#1.1 tsf显示的内存概述)

[1.2 正常情况与异常情况](#1.2 正常情况与异常情况)

[二 案例分析](#二 案例分析)

[2.1 case1 案例内存分析](#2.1 case1 案例内存分析)

[2.2 case2 案例GC分析](#2.2 case2 案例GC分析)

[2.3 case3案例内存分析](#2.3 case3案例内存分析)

[2.4 case4案例内存分析](#2.4 case4案例内存分析)

[2.5 case5案例内存分析](#2.5 case5案例内存分析)


一 背景说以及总结

1.1 tsf显示的内存概述

tsf显示的堆内存中,显示:max,used,committed 等指标的含义如下:

max:JVM 最多能用到多少内存(上限)

committed:操作系统已经分配给 JVM 的内存(已到手)

used:当前实际正在使用的内存(已消耗)

三者之间的关系:used ≤ committed ≤ max

例子如下:

used(当前堆)= 1209.43MB ≈ 1.2GB:你应用真正在用的内存,非常低,完全够用。

committed(已提交)= 4063MB ≈ 4GB:操作系统一次性全部分配给 JVM了4G,JVM 不用再动态申请内存。

max(最大堆)= 4063.00MB ≈ 4GB:JVM 能使用的上限,你只用到 1.2G,空间巨大。

1.2正常情况与异常情况

正常情况:

used 不断上涨 → 达到一定阈值

GC 自动回收 → used 突然下降

committed 按需扩容,但不会轻易接近 max

异常情况:

used 持续上涨,GC 后不下降 → 内存泄漏

used 不断逼近 max → 即将 OOM(内存溢出)

committed 快速达到 max → 无扩容空间,风险极高

二 案例分析

2.1 case1 案例内存分析

A)左上角:整体堆内存,完美的 "呼吸节奏"

业务运行不断创建对象 → used 稳步上涨

涨到一定程度触发GC回收 → used 瞬间掉下来

最关键的:每次GC后,内存的 "最低点" 都完全一样,没有越来越高!这直接排除了内存泄漏(泄漏的话,GC 后的最低点会一步步往上爬,像 "斜着的锯齿")

当前内存使用率最高才~55%,远低于 85% 的预警线,完全无压力。

B)左下角: eden区:标准的 Young GC 表现,这是最典型的新生代正常回收:

Eden 区是"新对象的临时托儿所",新对象都先放这

它的曲线就是:快速涨满 → 瞬间清空,周而复始,这说明你的 Young GC(新生代回收)非常高效,每次都能把 Eden 里朝生夕灭的临时对象几乎全回收掉,完全没有问题。

而且GC 频率很低,大概 1 小时才一次,说明应用压力非常小。

C****)右上角:非堆/元空间:完全稳定****

右上角的线几乎是平的,说明元空间(类元数据等)的内存使用非常稳定,没有异常增长。

D) 右下角:survicor区,正常的对象晋升工程。

Survivor区的小幅逐步上涨,完全符合 GC 逻辑:

每次Eden回收后,少量没死掉的存活对象,会挪到 Survivor 区"暂住"

所以Survivor 的使用量会慢慢攒一点,等对象年龄够了就会晋升到老年代

这里没有出现爆掉、或者突然暴涨的情况,说明 Survivor 空间足够,没有出现 "对象提前晋升老年代"的异常。

2.2 case2 案例GC分析

结论是:GC 和内存完全健康,没有任何问题,这是非常理想的运行状态!

A)左上角:老年代(Old Space):完全稳定,无任何堆积

老年代的内存使用量从始至终都是平的,一点都没涨:这说明长生命周期的对象(比如缓存、连接池)非常稳定,没有新增的泄漏对象,也没有大量新生代的对象晋升到老年代堆积,老年代空间非常充足,完全没压力,直接排除了内存泄漏的可能(泄漏的话老年代会一步步涨)

B)左下角:Young GC:周期稳定,回收高效

左下角的三个尖峰,就是三次 Young GC(新生代回收)每次 GC 的尖峰高度都一样,说明每次回收耗时很短(通常只有几十毫秒),对服务几乎没影响

周期很规律,大概1小时一次,说明应用压力很小,内存分配速度很慢

这和你之前那张 Eden 区的图完全对应,新生代回收非常高效,大部分对象都是朝生夕灭,在新生代就被回收了,根本没到老年代。

C)Full GC:一次都没发生过!这是最理想的状态

右下角的 Full GC监控线,全程都是平的:这说明老年代一直很空闲,根本不需要触发全堆回收,完全没有服务卡顿的风险

Full GC 会触发全堆停顿(STW),会卡住你的应用,是我们要尽量避免的!

行业内的健康标准就是:Full GC 越少越好,最好压根儿别发生!

D)右上角:元空间(Meta Space):稳定无异常

元空间的使用量也是平的,说明类元数据、方法区这些内存都很稳定,没有动态加载类导致的元空间泄漏,完全正常。

2.3 case3案例内存分析

结论:整体无严重问题,属于高负载下的稳定运行状态,没有内存泄漏。

A)左上角:Eden 区的频繁的GC:Eden 区的锯齿变得非常密,说明Young GC 变得很频繁(几分钟一次):这是因为业务流量上来了,对象创建的速度变快,Eden区很快就满了,但好消息是:每次 GC 后,Eden 的内存都能完全回收,回到同一个基线,说明新生代回收非常高效

而且这些频繁的 GC,没有导致对象大量晋升到老年代------ 老年代涨完之后就没动过,说明这些业务对象都是朝生夕灭的短生命周期对象,在新生代就被回收了,根本没到老年代,这是正常的。

B)左下角:老年代的 "突然跳涨":不是泄漏,是正常的一次性加载

老年代从~600M 直接跳到 1902M,之后就完全平了,这是典型的:

应用预热 / 缓存加载 :启动或某个时间点,一次性把所有缓存、全局配置、大的初始化数据加载到了内存里,这些都是长生命周期的对象,要长期驻留内存,所以加载完之后,老年代就稳定不动了,这和内存泄漏完全不同:泄漏是老年代持续一步步涨,而不是涨完就停了

当前老年代使用率:1902/2731 ≈ 70%****,属于健康区间,还没到触发 Full GC 的阈值,****只要后续不再涨,就完全没问题。

CD)右边的区域:

Survivor 区:全程平稳,没有溢出、没有异常增长

元空间:完全稳定,没有类加载泄漏

2.4 case4案例内存分析

结论:这是偶发的临时波动,没有严重问题,属于突发流量下的正常现象。

A)Survivor 区的尖峰:偶发的批量对象涌入,这个尖峰是典型的单次 Young GC 的临时现象:平时你的 Survivor 区只用了 1.18M,非常空闲

某个时间点,你可能遇到了突发的批量请求 / 临时大流量,产生了一批对象

触发 Young GC 的时候,这批对象刚好还存活,就一次性都被复制到了 Survivor 区,导致 Survivor 瞬间涨到接近满,然后下一次 GC 的时候,这些对象要么被回收了,要么年龄够了直接晋升到老年代了,所以 Survivor 马上就掉回了原来的低水位。

⚠️ 好消息是:这次尖峰没有超过 Survivor 的最大容量(112M),没有触发 "分配担保失败",也没有导致对象提前晋升到老年代,完全扛住了这次突发流量

B)右下角:Meta Space(元空间):全程平稳,没有任何波动,类元数据内存完全稳定。没有触发 Full GC:这次波动没有引发全堆回收,没有服务卡顿的情况

2.5 case5案例内存分析

1.左上角:整体堆内存(整个 JVM 堆的总使用情况)

前半段(03:00~05:00):

初始状态,JVM 给了一个比较大的新生代(结合整张图eden区域,oldspace区域研判,是新生代在gc),所以 1 小时才触发一次 GC,呈现 "大锯齿":内存涨到 2200M 左右,GC 后瞬间掉到 1000M,每次能回收 1.2G 内存,GC 间隔很长。

后半段(05:00 之后):

JVM 的自适应调优机制,自动把新生代的大小缩小了,所以 GC 变得非常频繁,锯齿变成了密集的小锯齿,波动范围稳定在 1600M~1800M 之间。

✅ 关键:调整完之后内存没有持续上涨,完全稳定,直接排除了内存泄漏。

  1. 右上角:非堆内存(堆之外的 JVM 内存)

全程都是一条平线,使用量一点都没变。

✅ 说明堆外内存、JVM 内部的其他内存都完全稳定,没有堆外内存泄漏,没有任何异常。

  1. 左下角:Eden Space(伊甸园区,新对象的诞生区)

前半段:

初始的 Eden 区很大,所以新对象慢慢涨,1 小时才把 Eden 填满,触发 GC 后瞬间清空,大锯齿和堆内存的变化完全对应。

后半段:

你能看到 Eden 的最大容量线(最上面的蓝线)突然降下来了 ------ 这就是 JVM 自动把 Eden 的大小缩小了!

所以 Eden 变小之后,对象创建速度没变,很快就满了,GC 变得非常频繁,变成了密集的小锯齿。

✅ 关键:每次 GC 后 Eden 都能完全清空,回收非常高效,只是空间变小了导致 GC 频率变高。

  1. 右下角:Survivor Space(幸存者区,存 Young GC 后存活的对象)

全程几乎是平的,只有最后有一点点微小的下降。

说明 Survivor 区的使用量非常稳定,JVM 调整新生代大小之后,Survivor 也跟着适配了,没有出现溢出、没有大量对象堆积,存活对象的晋升完全正常。

相关推荐
wechatbot8882 小时前
企业微信 iPad 协议客服机器人自动化管理平台开发指南
java·运维·微信·自动化·企业微信·ipad
草莓熊Lotso2 小时前
从 LLM 底层原理到 LangChain 全链路打通:大模型应用开发新征程
linux·运维·服务器·人工智能·langchain
zs宝来了2 小时前
网络篇11-本机网络IO工作原理
服务器·网络·tcp/ip
cyber_两只龙宝2 小时前
【Oracle】Oracle数据库的登录验证
linux·运维·数据库·sql·云原生·oracle
思麟呀2 小时前
5种IO模型
linux·运维·服务器·c++
YaBingSec2 小时前
玄机靶场-2024ccb初赛sc05 WP
android·运维·网络·笔记·安全·ssh
Andytoms2 小时前
小桔调研:3分钟Docker搭建问卷系统
运维·docker·容器
.千余2 小时前
【Linux】开发工具2:vim
linux·服务器·开发语言·学习
zzzsde2 小时前
【Linux】线程概念与控制(2)线程控制与核心概念
linux·运维·服务器·开发语言·算法