使用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 也跟着适配了,没有出现溢出、没有大量对象堆积,存活对象的晋升完全正常。

相关推荐
资料库011 小时前
Linux 8个常见运维故障排查
java·linux·运维
机核研创社2 小时前
睡裤明橡筋自动化选型指南与落地四步走
运维·自动化
志栋智能2 小时前
超自动化运维,告别复杂系统的新范式
运维·自动化
零基础1232 小时前
Ubuntu 常用命令汇总
linux·运维·开发语言
Android系统攻城狮2 小时前
Linux Gstreamer深度解析之gst_audio_sink_get_type调用流程与实战(六十五)
linux·运维·服务器·音视频·gstreamer音视频·音视频进阶·gstreamer音视频进阶
云贝贝贝4 小时前
PostgreSQL 分区表:从设计到运维,大表不再卡
运维·数据库·postgresql
zyseo84 小时前
谷歌SEO 站内搜索优化实战:把站内搜索词变成关键词金矿
java·服务器·数据库
王大傻09284 小时前
堆叠注入(Stacked Queries Injection)详解:原理、利用与防御
服务器·网络·数据库·web安全·网络安全
bigcarp4 小时前
安卓模拟器MUMU+tcpdump抓包Socket协议流量
服务器·网络·tcpdump
是个西兰花4 小时前
TCP套接字编程实战:从服务器搭建到多进程处理
服务器·网络协议·tcp/ip