杰瑞科技汇

Linux如何查看Java内存占用情况?

Java 内存区域

在查看内存之前,最好先了解一下 Java 内存的主要区域,这有助于你理解各种工具输出的含义:

Linux如何查看Java内存占用情况?-图1
(图片来源网络,侵删)
  1. 堆内存

    • 作用:存放对象实例和数组,是垃圾收集器管理的主要区域。
    • 查看:这是我们最常关注的部分,关注其已使用、最大和空闲容量。
  2. 非堆内存 / 元空间

    • 作用:存放类元数据、 JIT(即时编译器)编译后的代码缓存、线程等。
    • 查看:关注其使用情况,如果这里满了也可能导致 OutOfMemoryError
  3. 线程栈

    • 作用:每个线程在创建时都会分配一个私有的栈空间,用于存储局部变量、方法调用等。
    • 查看:关注线程数量和单个栈大小,如果线程过多或单个栈过大,会消耗大量内存。

使用 jpsjstat (JDK 内置工具)

这是最常用、最轻量级的方法,无需安装任何额外软件。

Linux如何查看Java内存占用情况?-图2
(图片来源网络,侵删)

步骤 1: 找到 Java 进程 ID

你需要查看当前系统中有哪些 Java 进程在运行。

# 显示所有 Java 进程的 ID 和主类名
jps
# 或者显示更详细的信息,包括 jar 包路径
jps -l

输出示例:

12345 com.example.MyApplication
67890 org.apache.catalina.startup.Bootstrap
9876 sun.tools.jps.Jps

这里的 1234567890 就是你需要关注的 Java 进程 ID。

步骤 2: 使用 jstat 查看内存统计

jstat 是一个强大的性能监控工具,可以实时查看 JVM 的各种运行时数据。

查看堆内存使用概览

# jstat -gc <PID> <interval> <count>
# PID: Java 进程 ID
# interval: 采样间隔(毫秒)
# count: 采样次数,不填则持续采样
# 示例:每 1 秒查看一次 PID 为 12345 的进程的 GC 情况,共 10 次
jstat -gc 12345 1000 10

输出解读:

 S0C    S1C    ...   UGCM    UGCT    ...   EU      OU     ...  YGC     YGCT    ...   GCT    ...
512.0   512.0  ...   0.00    0.000   ...   26.43   6.86   ...  2      0.050   ...   0.050  ...
512.0   512.0  ...   0.00    0.000   ...   26.43   6.86   ...  2      0.050   ...   0.050  ...
...
  • S0C / S1C: Survivor 0 和 Survivor 1 区的容量(Capacity)。
  • EC: Eden 区的容量。
  • OU: Old 区已使用的大小。
  • PU: Perm / Metaspace 区已使用的大小 (在 JDK 8+ 中为 Metaspace)。
  • YGC: Young GC 次数。
  • YGCT: Young GC 耗时。
  • FGC: Full GC 次数。
  • FGCT: Full GC 耗时。
  • GCT: 总 GC 耗时。
  • EU: Eden 区已使用的大小。
  • EU: Eden 区已使用的大小。

查看内存使用摘要

如果你想快速了解堆内存的总体情况,可以使用 -gccapacity 选项。

jstat -gccapacity 12345

输出解读:

 NGCMN    NGCMX     NGC     S0C   S1C       ... 
 8192.0   8192.0    8192.0  512.0  512.0     ...
  • NGCMN / NGCMX / NGC: New Generation (新生代) 的最小、最大和当前容量。
  • OGCMN / OGCMX / OGC: Old Generation (老年代) 的最小、最大和当前容量。
  • MetaspaceCM: Metaspace 的最大容量。

使用 jmap (JDK 内置工具)

jmap 主要用于生成 JVM 的内存转储快照,或者查看堆内存的详细信息。

生成堆转储文件

当怀疑内存泄漏时,可以使用 jmap 生成一个 .hprof 文件,然后用工具(如 Eclipse MAT, VisualVM)进行分析。

# jmap -dump:format=b,file=<filename.hprof> <PID>
# format=b 表示二进制格式
# 示例:为 PID 12345 生成堆转储文件 heapdump.hprof
jmap -dump:format=b,file=heapdump.hprof 12345

注意:生成堆转储是一个比较重的操作,可能会让 JVM 暂停,请在业务低峰期执行。

查看堆内存的直方图

可以查看堆中对象的数量和大小分布,有助于快速定位占用内存最多的对象类型。

# jmap -histo <PID>
# 如果想看到所有类(包括JDK内部类),加上 -all 选项
# 示例:查看 PID 12345 的对象直方图
jmap -histo 12345

输出解读:

 num     #instances         #bytes  class name
---------------------------------------
   1         150000        24000000  [C
   2          50000        16000000  java.lang.String
   3          10000         8000000  com.example.MyObject
...
  • #instances: 对象实例数量。
  • #bytes: 占用总字节数。
  • class name: 类名。

使用 top / htop (系统级工具)

这些是通用的 Linux 系统进程监控工具,可以快速查看一个进程占用了多少物理内存。

# 按内存使用率排序 (P: 按 CPU 排序, M: 按 内存 排序)
top
# 或者使用更友好的 htop
htop

然后按 M 键,找到你的 Java 进程,你会看到 RES (或 RESIDENT) 列,这表示该进程占用的物理内存大小。

  • 优点:快速、直观,无需任何 JDK 工具。
  • 缺点:无法区分 Java 堆内存、非堆内存等内部细节,只知道总的内存占用。

使用 jcmd (JDK 内置工具,JDK 7+)

jcmd 是一个多功能命令行工具,可以替代 jps, jstat, jmap 等多个工具,它通过向 JVM 发送命令来获取信息。

列出所有 Java 进程

jps -l
# 或者
jcmd

查看内存使用情况

# jcmd <PID> GC.heap_info
jcmd 12345 GC.heap_info

查看 GC 统计信息

# jcmd <PID> GC.class_histogram
# 功能与 jmap -histo 类似
jcmd 12345 GC.class_histogram
# jcmd <PID> GC.info
# 功能与 jstat -gc 类似
jcmd 12345 GC.info

使用可视化工具 (图形界面)

如果你不习惯命令行,可以使用图形化的监控工具。

VisualVM

VisualVM 是 JDK 自带的一款强大的监控、故障排查和性能分析工具。

  1. 启动:在终端输入 jvisualvm
  2. 连接:它会自动扫描并显示本地所有运行的 Java 应用,你也可以添加远程主机。
  3. 监控
    • 监控:实时查看 CPU、堆内存、类、线程等信息。
    • Sampler:可以抽样分析 CPU 和内存,查看哪个方法/对象最耗时/耗内存。
    • Visual GC:一个强大的插件,可以实时、图形化地展示 GC 的各个区域的活动情况,非常直观。

JConsole

JConsole 是另一个 JDK 自带的简单监控工具。

  1. 启动:在终端输入 jconsole
  2. 连接:选择要监控的本地进程。
  3. 监控:提供内存、线程、类等基本信息的图表视图,但比 VisualVM 简单。

总结与推荐

方法 命令 优点 缺点 适用场景
jps + jstat jps, jstat -gc 最常用、轻量级、信息详细、无需安装 命令行操作,需要解读输出 日常监控和快速检查,持续观察内存趋势和 GC 情况。
jmap jmap -dump, jmap -histo 能生成快照进行分析,查看对象分布 生成快照会暂停 JVM,较重 内存泄漏分析,需要深入堆内部查看对象时。
top / htop top (按 M 排序) 最快速、系统级通用 无法区分 JVM 内部内存区域 快速检查 Java 进程总的物理内存占用
jcmd jcmd, jcmd ... GC.heap_info 功能强大,统一入口,可远程 相对较新,命令参数较多 JDK 7+ 环境,需要执行多种 JVM 命令。
VisualVM jvisualvm 图形化界面、功能全面、集成 Visual GC 需要启动 GUI,略显笨重 深度分析实时监控,特别是需要图形化查看 GC 时。

实践建议

  1. 日常巡检:使用 tophtop 快速查看 Java 进程的总内存占用,如果发现异常,再使用 jstat -gc <PID> 深入查看堆内存和 GC 情况。
  2. 性能调优/问题排查:启动 VisualVM,利用其图形化界面(特别是 Visual GC 插件)实时观察 JVM 内部状态,结合 jmap -histo 分析对象。
  3. 怀疑内存泄漏:使用 jmap -dump 生成堆快照,然后用 Eclipse MAT 等工具进行分析,找到无法被回收的对象。

希望这份详细的指南能帮助你更好地在 Linux 上监控 Java 应用的内存!

分享:
扫描分享到社交APP
上一篇
下一篇