使用Tomcat部署war包查看内存使用情况
前言:
使用Tomcat部署多个war包,只有一个Java进程,使用常用方式只能看到整体占用内存情况。比如ps -aux 查看进程详情,或者使用jmap -heap查看JVM堆内存。
如果想要看到每个war包对应的服务占用多少内存,提供如下两种简单的方式。
方式一:配置Actuator端点
1、在项目配置文件中添加
# 开放端点
management.endpoints.web.exposure.include=health,info,metrics
# 是否开启metrics端点,可以不配置
management.endpoint.metrics.enabled=true
2、用法
(1)查看全部指标
http://ip:port/actuator/metrics
{"names": ["jvm.buffer.count","jvm.buffer.memory.used","jvm.buffer.total.capacity","jvm.classes.loaded","jvm.classes.unloaded","jvm.gc.live.data.size","jvm.gc.max.data.size","jvm.gc.memory.allocated","jvm.gc.memory.promoted","jvm.gc.pause","jvm.memory.committed","jvm.memory.max","jvm.memory.used","jvm.threads.daemon","jvm.threads.live","jvm.threads.peak","jvm.threads.states","logback.events","process.cpu.usage","process.files.max","process.files.open","process.start.time","process.uptime","system.cpu.count","system.cpu.usage","system.load.average.1m","tomcat.cache.access","tomcat.cache.hit","tomcat.global.error","tomcat.global.received","tomcat.global.request","tomcat.global.request.max","tomcat.global.sent","tomcat.servlet.error","tomcat.servlet.request","tomcat.servlet.request.max","tomcat.threads.busy","tomcat.threads.config.max","tomcat.threads.current"]
}
常用内置指标端点
指标类别 | 端点路径示例 | 说明 |
---|---|---|
JVM内存 | /actuator/metrics/jvm.memory.used | JVM内存使用情况 |
HTTP请求 | /actuator/metrics/http.server.requests | Web请求统计 |
系统CPU | /actuator/metrics/system.cpu.usage | CPU使用率 |
垃圾收集 | /actuator/metrics/jvm.gc.pause | GC暂停时间 |
进程信息 | /actuator/metrics/process.uptime | 应用运行时间 |
(2)查看内存
http://ip:port/actuator/metrics/jvm.memory.used
说明:value是jvm全部占用内存,包括堆(PS Eden Space、PS Survivor Space、PS Old Gen)和非堆(Metaspace、Compressed Class Space、Code Cache)空间,单位bytes。转换成MB(/1024/1024)。
{"name": "jvm.memory.used","description": "The amount of used memory","baseUnit": "bytes","measurements": [{"statistic": "VALUE","value": 9897020928}],"availableTags": [{"tag": "area","values": ["heap","nonheap"]},{"tag": "id","values": ["Compressed Class Space","PS Survivor Space","PS Old Gen","Metaspace","PS Eden Space","Code Cache"]}]
}
(3)查看内存详细指标
格式:jvm.memory.used?tag=area:heap
比如,堆内存:http://ip:port/actuator/metrics/jvm.memory.used?tag=area:heap
{"name": "jvm.memory.used","description": "The amount of used memory","baseUnit": "bytes","measurements": [{"statistic": "VALUE","value": 8406602104}],"availableTags": [{"tag": "id","values": ["PS Eden Space","PS Survivor Space","PS Old Gen"]}]
}
非堆内存:http://ip:port/actuator/metrics/jvm.memory.used?tag=area:nonheap
{"name": "jvm.memory.used","description": "The amount of used memory","baseUnit": "bytes","measurements": [{"statistic": "VALUE","value": 1519950712}],"availableTags": [{"tag": "id","values": ["Metaspace","Compressed Class Space","Code Cache"]}]
}
方式二:通过代码获取
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;public class MemoryMonitor {public static void main(String[] args) {// 获取堆内存使用MemoryMXBean memoryMxBean = ManagementFactory.getMemoryMXBean();MemoryUsage heapUsage = memoryMxBean.getHeapMemoryUsage();System.out.println("Heap Memory Used: " + heapUsage.getUsed() / 1024 / 1024 + " MB");// 获取各内存池详情for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {MemoryUsage usage = pool.getUsage();System.out.printf("Pool: %s, Used: %d MB%n", pool.getName(), usage.getUsed() / 1024 / 1024);}}
}
输出:
Memory Monitor:
Heap Memory Used: 7931 MB
Pool: Code Cache, Used: 152 MBPool: Metaspace, Used: 1149 MB
Pool: Compressed Class Space, Used: 144 MB
Pool: PS Eden Space, Used: 2060 MB
Pool: PS Survivor Space, Used: 140 MB
Pool: PS Old Gen, Used: 5730 MB
关键内存区域说明
内存区域 | 说明 |
---|---|
G1 Eden Space | 年轻代Eden区,新对象首先分配在这里 |
G1 Survivor Space | 年轻代Survivor区,存放从Eden区GC后存活的对象 |
G1 Old Gen | 老年代,存放长期存活的对象 |
Metaspace | 存储类元数据(取代永久代),不包含在堆内存中 |
Code Cache | JIT编译后的本地代码存储区域 |
Compressed Class Space | 压缩指针使用的类空间 |