Tomcat是一款常用的Web容器, 它是运行在 JVM(Java Virtual Machine) 中的一个Java进程.

本文以Tomcat为例, 借助一些JDK的工具对Tomcat在运行过程中的内存占用情况进行监控, 为优化提供数据支撑.

1 JDK 工具的使用

JDK自带的工具位于${JAVA_HOME}/bin/目录下.

JConsole 可以简单明了地查看到内存的使用情况, 线程的状态, 当前加载的类的总量等.

JVisualVM 可以下载插件(如GC等), 进而查看更丰富的信息. 如果是分析本地的Tomcat的话, 还可以进行内存抽样等, 检查每个类的使用情况.

(1) jps 查看本地运行着的 Java 进程, 及其进程号、进程启动的路径等信息;

(2) jmap 查看垃圾收集策略即 JVM 内存占用情况:

jmap -heap pid # 查看垃圾收集策略, 以及堆内存的分配与使用情况.

jmap -clstats pid # 查看类加载器的统计数据 —— 此命令调用了sun.jvm.hotspot.runtime.VM.initialize() 方法, 会导致该 pid 对应的 JVM 进程阻塞.

jmap -histo [pid] # 按照内存使用大小倒序列出内存中的实例类型.

(3) jstack 查看线程栈:

jstack pid # 列出该 pid 对应 JVM 的所有线程栈描述, 主要包括每个线程的状态以及堆栈内各栈帧的方法全限定名、代码位置. 注意: 这些信息的显示只是为了便于开发人员阅读, 并不是栈中存的就是这些信息.

(4) jstat 实时查看堆内存的使用情况:

  1. # 使用方法:
  2. jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
  3. # 查看可使用的选项:
  4. jstat options
  5. -class # 类加载情况的统计
  6. -compiler # HotSpot中即时编译器编译情况的统计
  7. -gc
  8. -gccapacity # 新生代、老年代以及永久代的存储容量情况
  9. -gccause
  10. -gcmetacapacity # 元数据区的容量
  11. -gcnew # 新生代垃圾回收信息
  12. -gcnewcapacity # 新生代的存储容量
  13. -gcold # 老年代垃圾回收信息
  14. -gcoldcapacity # 老年代的存储容量
  15. -gcutil # 实时查看GC信息
  16. -printcompilation # HotSpot编译方法的统计
  • 使用示例: 间隔5s, 每隔10条输出一次头信息, 打印进程号为3308的JVM进程的堆内存使用情况, 以及各代垃圾回收的次数及时间:

    jstat -gcutil -h10 77545 5000

  • 显示信息如下:

  • 参数说明:

    1. S0: Heap上的Survivor Space 0区已使用空间的百分比
    2. S1: Heap上的Survivor Space 1区已使用空间的百分比
    3. E: Heap上的Eden Space区已使用空间的百分比
    4. O: Heap上的Old Space区已使用空间的百分比
    5. M: Meta Space(元数据区)已使用空间的百分比
    6. YGC: 从应用程序启动到采样时发生Young GC的次数
    7. YGCT: 从应用程序启动到采样时Young GC所用的时间(单位: 秒)
    8. FGC: 从应用程序启动到采样时发生Full GC的次数
    9. FGCT: 从应用程序启动到采样时Full GC所用的时间(单位: 秒)
    10. GCT: 从应用程序启动到采样时用于垃圾回收的总时间(单位: 秒)

2 查看 GC 日志信息

可以通过配置JVM的启动参数, 打印类的加载情况及对象的回收信息, 可以打印到屏幕或指定文件中, 默认也会打印到catalina.log中. Tomcat容器的JVM启动参数配置文件是: ${TOMCAT_HOME}/bin/catalina.sh, 具体参数如下:

  1. -verbose:gc
  2. # 在输出设备显示垃圾收集信息(JVM发生内存回收时输出相关信息)
  3. -XX:+PrintGC
  4. # 输出GC日志, 形式: Full GC 118250K->113543K(130112K), 0.0094143 secs
  5. -XX:+PrintGCDetails
  6. # 输出GC详细日志, 形式: GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs[Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]
  7. -XX:+PrintGCTimeStamps
  8. # 输出GC的时间戳, 以基准时间的形式输出: 11.851: [GC 98328K->93620K(130112K), 0.0082960 secs], 11.851是JVM启动后的秒数.
  9. -XX:+PrintGCDateStamps
  10. # 输出GC的时间戳, 以日期的形式输出: 2018-08-28T21:53:59.234+0800
  11. -XX:+PrintGCApplicationStoppedTime
  12. # 打印垃圾回收期间程序暂停的时间, 即GC消耗的时间. 可与上面混合使用.
  13. # 输出形式: Total time for which application threads were stopped: 0.0468229 seconds
  14. -XX:+PrintGCApplicationConcurrentTime
  15. # 打印每次垃圾回收前, 程序未中断的执行时间, 即相邻2次GC的间隔.
  16. # 可以和上面的配置混合使用. 输出形式: Application time: 0.5291524 seconds
  17. -XX:+PrintTenuringDistribution
  18. # 观察各个Age的对象总大小
  19. -XX:PrintHeapAtGC
  20. # 打印GC前后的详细堆栈信息
  21. -XX:+HeapDumpOnOutOfMemoryError
  22. # 发生OOM时自动dump堆栈信息, 以便后续分析
  23. -Xloggc:../logs/gc.log
  24. # 与上面选项配合使用, 将日志信息输出到指定的文件以便后续分析

3 添加 JMS 远程监控

对部署在局域网内其他服务器上的Tomcat, 可以打开JMX监控端口, 就可以在另外的服务器上通过该端口查看常用的参数(一些比较复杂的功能不支持).

配置方法: 同样是在JVM启动参数中配置, 配置如下:

  1. -Dcom.sun.management.jmxremote.ssl=false
  2. -Dcom.sun.management.jmxremote.authenticate=false
  3. -Djava.rmi.server.hostname=172.16.11.62 # 设置JVM的JMS监听的IP地址, 防止错误监听为本机127.0.0.1地址
  4. -Dcom.sun.management.jmxremote.port=1090 # 设置JVM的JMS监控的端口
  5. -Dcom.sun.management.jmxremote.ssl=false # 设置JVM的JMS监控不实用SSL
  6. -Dcom.sun.management.jmxremote.authenticate=false # 设置JVM的JMS监控不需要认证

参考资料

JVM 运行时内存使用情况监控

版权声明

作者: 马瘦风

出处: 博客园 马瘦风的博客

您的支持是对博主的极大鼓励, 感谢您的阅读.

本文版权归博主所有, 欢迎转载, 但请保留此段声明, 并在文章页面明显位置给出原文链接, 否则博主保留追究相关人员法律责任的权利.

通过JDK常用工具监控Java进程的内存占用情况的更多相关文章

  1. [2017-08-09]一则使用WinDbg工具调试iis进程调查内存占用过高的案例

    最近遇到一个奇葩内存问题,跟了三四天,把Windbg玩熟了,所以打算分享下. 症状简介 我们团队的DEV开发环境只有一台4核16G的win2012r2. 这台服务器上装了SqlServer.TFS(项 ...

  2. 【转】一则使用WinDbg工具调试iis进程调查内存占用过高的案例

    最近遇到一个奇葩内存问题,跟了三四天,把Windbg玩熟了,所以打算分享下. 症状简介 我们团队的DEV开发环境只有一台4核16G的win2012r2.这台服务器上装了SqlServer.TFS(项目 ...

  3. linux 查看Java 进程的内存使用情况

    top -b -n 1 | grep java| awk '{print "PID:"$1",mem:"$6",CPU percent:"$ ...

  4. JDK常用工具

    JDK的命令行工具 jps 查看正在使用的jvm机器进程号. 常用命令,-l显示正在运行的jar包或者软件(基于jvm),-v显示当前进程详细的jvm参数 jps -l jps -v javap 反汇 ...

  5. 利用VisualVm和JMX远程监控Java进程

    自Java 6开始,Java程序启动时都会在JVM内部启动一个JMX agent,JMX agent会启动一个MBean server组件,把MBeans(Java平台标准的MBean + 你自己创建 ...

  6. Zabbix 通过 JMX 监控 java 进程

    参考: [ JMX monitoring ] [ Zabbix Java gateway ] [ JMX Monitoring (Java Gateway) not Working ] [ Monit ...

  7. linux Java项目CPU内存占用高故障排查

    linux Java项目CPU内存占用高故障排查 top -Hp 进程号 显示进程中每个线程信息,配合jstack定位java线程运行情况 # 线程详情 jstack 线程PID # 查看堆内存中的对 ...

  8. linux下对进程按照内存使用情况进行排序

    linux下对进程按照内存使用情况进行排序的命令为:ps aux --sort -rss 详细解说参见 http://alvinalexander.com/linux/unix-linux-proce ...

  9. MFC下获取系统内存和当前进程的内存使用情况

    GlobalMemoryStatusEx来获取系统的内存使用情况 GetProcessMemoryInfo获取某个进程的内存使用情况.和任务管理器看到的是一样的. 具体代码如下: void GetSy ...

随机推荐

  1. html居中定位

    <!DOCTYPE html PUBLIC "-//W3C//Ddiv XHTML 1.0 divansitional//EN" "http://www.w3.or ...

  2. jenkins构建基于gradle的springboot项目CI采坑(采用jar方式部署)

    试了一堆插件,最后用的还是 publish over SSH jenkins基本配置不多说了,就是配置一下git仓储,配置一下gradle执行命令 clean bootRepackage 之后执行Se ...

  3. 人脸检测? 对Python来说太简单, 调用dlib包就可以完成

    "Dlib 是一个现代化的 C ++ 工具包,包含用于创建复杂软件的机器学习算法和工具 " .它使您能够直接在 Python 中运行许多任务,其中一个例子就是人脸检测. 安装 dl ...

  4. AUTOSAR ArcticCore重构 - for_each_HOH

    Arctic Core是AUTOSAR的实现,早期版本是开源的. 基本问题 在ARM架构下对CAN driver的实现(arch/arm/arm_cm3/drivers/Can.c)中,有这样一段代码 ...

  5. Windows10 Ubuntu bash 配置 LAMP+JDK+Tomcat

    Windows10的Bash省去了装ubuntu虚拟机的麻烦,而且可以直接用Windows下的浏览器去访问了,Exciting有没有,再也不用去忍受日常崩溃的chromium和慢慢的firefox了. ...

  6. MicroService 微服务架构模式简述

    开源地址: https://github.com/TheCodeCleaner/MicroService4Net 本文内容 微服务 微服务风格的特性 组件化(Componentization )与服务 ...

  7. PHP 的 uniqid 函数产生的 id 真的是唯一的么?

    PHP 的 uniqid 函数产生的 id 真的是唯一的么? 最近使用到了 uniqid,就产生了疑问?uniqid 生成的 id 由什么组成?真的是唯一的么?什么情况下会产生冲突? 从文档中看到 u ...

  8. FPGA学习笔记(二)——FPGA学习路线及开发流程

    ###### [该随笔部分内容转载自小梅哥]       ######### 一.FPGA学习路线 工具使用 -> 语法学习 -> 逻辑设计 -> IP使用 ->接口设计 -& ...

  9. 接口测试返回的json文件中字符串是乱序

    问题描述 接口测试中post方式匹配返回信息时显示不匹配, 但是statuscode明明是200, 而且用postman /restclient等工具测出来也是没问题的. 根本原因 封装了这么个方法来 ...

  10. 「关于一种处理关于$p$成多项式的数论函数筛法」

    张博航原知乎网址 张博航原博客网址 引入: 给一个完全积性函数$f$,求其前缀和 $$S(n)=\sum_{i=1}^nf(i)$$ 初步思考: 考虑由于所求函数为完全积性函数,我们很容易用一个线性筛 ...