UNIX内存占用基本检查

博客聚焦于UNIX系统,主要介绍了对其内存占用进行基本检查的相关内容,属于信息技术中操作系统领域。

UNIX内存占用基本检查

1: 使用top指令.

  top指令是按cpu占用率排序的,如果想一次获得所有进程的快照,使用命令

top -n [最大进程数] -f 输出到文件,比如top -n 1000 -f topsnapshot.log

  top指令输出内存的统计信息包括

Memory: 2614368K (2249100K) real, 5838616K (5264696K) virtual, 113028K free  Page# 1/1
其中没有括号起来的是总数,括号括起来的部分是活动进程使用的内存数,free则是真实空闲的物理内存数.

进程信息的列包括

CPU TTY  PID USERNAME PRI NI   SIZE    RES STATE    TIME %WCPU  %CPU COMMAND

和内存相关的只有SIZE和RES

SIZE:任务的代码加上数据再加上栈空间的大小。
RES:任务使用的物理内存的总数量

要检查进程是否有内存泄露,和实际占用的内存大小,看RES列即可.

2:检查共享内存占用的内存容量

使用ipcs -m -b命令,-m表示检查共享内存,-b表示输出每个内存的字节数,得到的共享内存信息输出列包括:

T         ID     KEY        MODE        OWNER     GROUP      SEGSZ

SEGSZ列则是字节数.把每列相加则是共享内存占用的内存总数.

3: 调整内核动态高速缓冲区参数

HP-UX某些型号的服务器运行的时候需要几乎1G的内存维持系统运行,比如作为设备缓冲什么的.

可以用kmtune命令检查内核配置参数,动态高速缓冲区参数dbc_min_pct 和 dbc_max_pct参数表示一个高速缓冲区允许的可用内存的最小和最大百分比,dbc_max_pct的缺省值是50,一般设置为10即可.

4:在HP-UX上还可以使用glance

glance是个很强的工具,可惜不是免费的....

### 回答问题:如何检查 Java 程序占用了多少内存? --- ## ✅ 核心回答 要准确检查一个 **Java 程序占用内存**,不能只看堆内存(Heap),而应从两个层面分析: 1. **JVM 堆内存使用情况**(可通过 Java API 或工具查看) 2. **整个 JVM 进程的实际物理内存占用(RSS)**(操作系统级别) 因为 Java 应用的总内存 = 堆 + 元空间 + 线程栈 + 直接内存 + 代码缓存 + GC 和 JIT 开销,所以仅看堆会严重低估实际使用量。 --- ## ✅ 一、方法 1:通过 `jstat` 查看内存使用(最常用) ```bash # 获取进程 PID jps -l # 查看内存和 GC 情况(每秒刷新一次) jstat -gc <pid> ``` 输出示例: ``` S0C S1C S0U S1U EC EU OC OU 1024.0 1024.0 0.0 512.0 8192.0 6500.0 20480.0 12000.0 ``` 📌 计算堆使用量: - **已用堆内存 = EU + SU + OU ≈ 6500 + 512 + 12000 = 19,012 KB ≈ 18.6 MB** - 最大堆大小 = `-Xmx` 设置值(可用 `jinfo <pid>` 查看) > ⚠️ 注意:这只是堆内存,不包括其他部分。 --- ## ✅ 二、方法 2:通过 `jmap -heap` 查看堆详细信息 ```bash jmap -heap <pid> ``` 输出内容包含: - 使用的垃圾收集器 - 堆初始大小(init)、当前大小(current)、最大大小(max) - 新生代、老年代配置 📌 示例片段: ``` Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 4294967296 (4096.0MB) NewSize = 143130624 (136.5MB) ... Heap Usage: PS Young Generation Eden Space: capacity = 80740352 (77.0MB) used = 65000000 (62.0MB) ... PS Old Generation capacity = 2863661056 (2731.0MB) used = 1200000000 (1144.5MB) ``` 👉 总堆使用 ≈ 62 + 1144.5 = **1206.5 MB** --- ## ✅ 三、方法 3:查看整个 JVM 进程的真实内存占用(推荐用于生产) Java 程序实际占用内存远大于堆内存。建议使用以下命令查看操作系统级别的内存使用: ### ✅ Linux/Unix: 使用 `ps` 命令 ```bash # 查看指定 PID 的 RSS(常驻内存) ps -p <pid> -o pid,ppid,cmd,rss,size,vsize # 示例输出: # PID PPID CMD RSS SIZE VSZ # 12345 12344 java ... 210500 210500 4198528 ``` - **RSS (Resident Set Size)**:实际使用的物理内存(单位 KB)→ **210,500 KB ≈ 205.6 MB** - **VSZ (Virtual Memory Size)**:虚拟内存总量(含映射文件等) 📌 推荐命令(简洁输出 RSS): ```bash ps -p $(jps | grep YourApp | awk '{print $1}') -o rss=,vsz= ``` --- ### ✅ 更精确监控:使用 `top` 或 `htop` ```bash top -p <pid> ``` 在交互界面中可看到: - `%MEM`:内存使用百分比 - `RES`:常驻内存(即 RSS) - `VIRT`:虚拟内存 --- ## ✅ 四、方法 4:编程方式获取 JVM 内存使用(Java 代码) ```java import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryUsage; public class MemoryUsageChecker { public static void printMemoryUsage() { // 获取堆内存信息 MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage(); MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage(); System.out.printf("【堆内存】已使用: %.2f MB, 提交: %.2f MB, 最大: %.2f MB%n", heapUsage.getUsed() / 1024.0 / 1024.0, heapUsage.getCommitted() / 1024.0 / 1024.0, heapUsage.getMax() / 1024.0 / 1024.0); System.out.printf("【非堆内存】已使用: %.2f MB, 提交: %.2f MB%n", nonHeapUsage.getUsed() / 1024.0 / 1024.0, nonHeapUsage.getCommitted() / 1024.0 / 1024.0); // 注意:无法直接获取 native 内存(如线程栈、直接内存) } public static void main(String[] args) { printMemoryUsage(); } } ``` 📌 输出示例: ``` 【堆内存】已使用: 1206.50 MB, 提交: 2048.00 MB, 最大: 4096.00 MB 【非堆内存】已使用: 380.20 MB, 提交: 400.00 MB ``` > ❗注意:这仍不包括线程栈、DirectBuffer、JIT 编译代码等 native 内存! --- ## ✅ 五、完整内存构成图解(Java 应用总内存) | 内存区域 | 是否包含在堆中 | 说明 | |--------|----------------|------| | Heap (Eden/Survivor/Old) | ✅ 是 | `-Xms`, `-Xmx` 控制 | | Metaspace | ❌ 否 | 类元数据,受 `-XX:MaxMetaspaceSize` 控制 | | Compressed Class Space | ❌ 否 | 存储压缩类指针数据 | | Thread Stacks | ❌ 否 | 每个线程默认 1MB(64位),大量线程时很耗内存 | | Direct Buffers | ❌ 否 | NIO 中通过 `ByteBuffer.allocateDirect()` 分配 | | Code Cache | ❌ 否 | JIT 编译后的本地代码存储区 | | GC & Internal Overhead | ❌ 否 | GC 数据结构、JVM 内部对象 | 📌 实际经验公式: > **JVM 总内存 ≈ 堆大小 × 1.2 ~ 1.5** > 若开启大量线程或使用 Netty/MappedByteBuffer,则可能更高。 --- ## ✅ 六、最佳实践建议 | 场景 | 推荐方法 | |------|----------| | 开发调试 | `jstat -gc <pid>` + `jmap -histo` | | 内存泄漏排查 | `jmap -dump:format=b,file=heap.hprof <pid>` + MAT 分析 | | 容器环境监控 | `ps -p <pid> -o rss=` 结合 Prometheus Exporter | | 自动化监控 | 编写脚本定时采集 `jstat` 和 `ps` 数据 | --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值