如何监控 Tomcat 的内存占用情况

目录

  • 1 JVM 内存模型中的区域

    • 1.1 线程栈区
    • 1.2 Java Heap 区
    • 1.3 静态方法区
    • 1.4 JDK 8.0中的元空间
  • 2 JDK 工具的使用
  • 3 查看 GC 日志信息
  • 4 添加 JMS 远程监控

Tomcat 是运行在 JVM(Java Virtual Machine) 中的一个 Java 进程, 它在运行过程中对内存的占用情况, 可以借助一些 JDK 的工具进行监控, 为优化提供数据支撑.

1 JVM 内存模型中的区域

1.1 线程栈区

压入线程栈的每个栈帧(Stack Frame)中, 包含了程序指令以及局部变量表, 每个方法调用对应一个栈帧.

程序指令包括程序计数器(PCR), 记录程序执行到的位置, 便于方法调用或多线程切换结束后的工作恢复.

局部变量表包括各种基本数据类型: boolean、byte、char、short、int、float、long、double以及对象的引用.

注意: 每个线程都有独立的栈, 称之为线程栈, 它们是互相隔离的.

1.2 Java Heap 区

Java Heap是被所有线程共享的一块内存区域, 在虚拟机启动时创建. 此内存区域的唯一目的就是存放对象实例, 几乎所有的对象实例都在这里分配内存.

1.3 静态方法区

又称为永久代(Perm Generation), 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据.

对于永久代的常见配置有: -XX:PermSize=256m -XX:MaxPermSize=512m.

说明: JDK 8.0中用Meta Space(元空间)替代Perm Generation, 因此在配置 JVM 启动参数的时候, 需要作如下配置:

-XX:MetaspaceSize=256m     # 对比JDK 7.0的 PermSize
-XX:MaxMetaspaceSize=512m  # 对比JDK 7.0的 MaxPermSize

1.4 JDK 8.0中的元空间

JDK 8.0 的HotSpot 实现中, 使用本地内存来存储类的元数据, 这个区域被称为元空间.

  • 元空间有如下特点:

    1. 充分利用了Java语言规范中的好处: 类及相关元数据的生命周期与类加载器的生命周期一致;
    2. 每个类加载器都有各自专用的存储空间;
    3. 元空间只进行线性分配;
    4. 不会单独回收某个类;
    5. 省掉了GC扫描及压缩的时间;
    6. 元空间中对象的位置是固定的;
    7. 如果GC发现某个类加载器不再存活, 它就会把与这个类加载器相关的空间全部回收.
  • 元空间的内存分配模型:
    1. 绝大多数类的元数据空间都从本地内存中分配;
    2. 用来描述类的元数据的类也被删除了;
    3. 分元数据分配了多个虚拟内存空间;
    4. 给每个类加载器分配一个内存块的列表, 块的大小取决于类加载器的类型; sun/反射/代理对应的类加载器的块会小一些;
    5. 归还内存块, 释放内存块列表;
    6. 一旦元空间的数据被清空了, 虚拟内存的空间就会被回收;
    7. 减少碎片的策略.

2 JDK 工具的使用

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

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

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

  • jps 查看本地运行着的 Java 进程, 及其进程号、进程启动的路径等信息;
  • jmap 查看垃圾收集策略即 JVM 内存占用情况:

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

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

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

  • jstack 查看线程栈:

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

  • jstat 实时查看堆内存的使用情况:
    # 使用方法:
    jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
    # 查看可使用的选项:
    jstat –options
    -class            # 类加载情况的统计
    -compiler         # HotSpot中即时编译器编译情况的统计
    -gc
    -gccapacity       # 新生代、老年代以及永久代的存储容量情况
    -gccause
    -gcmetacapacity   # 元数据区的容量
    -gcnew            # 新生代垃圾回收信息
    -gcnewcapacity    # 新生代的存储容量
    -gcold            # 老年代垃圾回收信息
    -gcoldcapacity    # 老年代的存储容量
    -gcutil           # 实时查看GC信息
    -printcompilation # HotSpot编译方法的统计
    • 使用示例: 间隔5s, 每隔10条输出一次头信息, 打印进程号为3308的JVM进程的堆内存使用情况, 以及各代垃圾回收的次数及时间:
      jstat -gcutil -h10 77545 5000
    • 显示信息如下:
    • 参数说明:
    S0: Heap上的Survivor Space 0区已使用空间的百分比
    S1: Heap上的Survivor Space 1区已使用空间的百分比
    E:  Heap上的Eden Space区已使用空间的百分比
    O:  Heap上的Old Space区已使用空间的百分比
    M:  Meta Space(元数据区)已使用空间的百分比
    YGC: 从应用程序启动到采样时发生Young GC的次数
    YGCT: 从应用程序启动到采样时Young GC所用的时间(单位: 秒)
    FGC:  从应用程序启动到采样时发生Full GC的次数
    FGCT: 从应用程序启动到采样时Full GC所用的时间(单位: 秒)
    GCT:  从应用程序启动到采样时用于垃圾回收的总时间(单位: 秒)

3 查看 GC 日志信息

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

-verbose:gc          # 在输出设备显示垃圾收集信息(JVM发生内存回收时输出相关信息)
-XX:+PrintGC         # 输出GC日志, 形式: Full GC 118250K->113543K(130112K), 0.0094143 secs
-XX:+PrintGCDetails  # 输出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] 

-XX:+PrintGCTimeStamps  # 输出GC的时间戳, 以基准时间的形式输出: 11.851: [GC 98328K->93620K(130112K), 0.0082960 secs], 11.851是JVM启动后的秒数.
-XX:+PrintGCDateStamps  # 输出GC的时间戳, 以日期的形式输出: 2018-08-28T21:53:59.234+0800. 

-XX:+PrintGCApplicationStoppedTime     # 打印垃圾回收期间程序暂停的时间, 即GC消耗的时间. 可与上面混合使用. 输出形式: Total time for which application threads were stopped: 0.0468229 seconds
-XX:+PrintGCApplicationConcurrentTime  # 打印每次垃圾回收前, 程序未中断的执行时间, 即相邻2次GC的间隔. 可与上面混合使用. 输出形式: Application time: 0.5291524 seconds 

-XX:+PrintTenuringDistribution   # 观察各个Age的对象总大小
-XX:PrintHeapAtGC                # 打印GC前后的详细堆栈信息.
-XX:+HeapDumpOnOutOfMemoryError  # 发生OOM时自动dump堆栈信息, 以便后续分析. 

-Xloggc:../logs/gc.log     # 与上面选项配合使用, 将日志信息输出到指定的文件以便后续分析. 

4 添加 JMS 远程监控

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

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

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

参考资料:
JVM 运行时内存使用情况监控

版权声明

作者: ma_shoufeng(马瘦风)

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

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

本文版权归博主所有, 欢迎转载, 但未经博主同意必须保留此段声明, 且在文章页面明显位置给出原文链接, 否则博主保留追究法律责任的权利.

原文地址:https://www.cnblogs.com/shoufeng/p/9673975.html

时间: 2024-10-12 15:29:33

如何监控 Tomcat 的内存占用情况的相关文章

内存管理[6]测试堆的内存占用情况

本例效果图: unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls; type   TForm1 = class(TForm)     Button1: TButton;     Button2: TButton;     Memo1: TMemo;     Memo2: TMemo;     proce

【经验】使用Profiler工具分析内存占用情况

Unity3D为我们提供了一个强大的性能分析工具Profiler.今天我们就使用Profiler来详细分析一下官方例子AngryBots的内存使用信息数据. 首先打开Profiler选择Memory选项,在游戏运行的某一帧查看Detailed选项数据(Simple模式的数据很直观,可以知道内存大体被哪部分占用了,网上也有很多相关介绍,我就不再啰嗦了),如下图所示: 选中后,unity会自动获取这一帧的内存占用数据项,主要分为:Other.Assets.BuiltinResources.Scene

查看LINUX进程内存占用情况

可以直接使用top命令后,查看%MEM的内容.可以选择按进程查看或者按用户查看,如想查看oracle用户的进程内存使用情况的话可以使用如下的命令: (1)top top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 可以直接使用top命令后,查看%MEM的内容.可以选择按进程查看或者按用户查看,如想查看oracle用户的进程内存使用情况的话可以使用如下的命令: $ top -u oracle 内容解释: PID:进程的ID USE

Android使用procrank和dumpsys meminfo分析内存占用情况

如果你想查看所有进程的内存使用情况,可以使用命令procrank.dumpsys meminfo查看,当然也只可以过滤出某个进程如:dumpsys meminfo | grep -i phone 先来看下procrank 1 sh-4.2# procrank 2 PID Vss Rss Pss Uss cmdline 3 1078 59840K 59708K 42125K 39344K com.csr.BTApp 4 2683 59124K 59040K 37960K 33032K com.an

Android使用procrank和dumpsysmeminfo分析内存占用情况

如果你想查看所有进程的内存使用情况,可以使用命令procrank.dumpsys meminfo查看,当然也只可以过滤出某个进程如:dumpsys meminfo | grep -i phone 先来看下procrank view sourceprint? 01. sh-4.2# procrank 02. PID Vss Rss Pss Uss cmdline 03. 1078 59840K 59708K 42125K 39344K com.csr.BTApp 04. 2683 59124K 5

怎样正确查看Linux的内存占用情况

昨天下午客户那边反馈,说服务器里面32G的内存通过TOP查看,已经用了31G多的,让我处理解决.我当时过程过去一看,刚开始也认为是内存快满了,晚上回去做了个24小时的稳定性测试,探讨了Linux的Mem使用情况: 查看内存最方便的命令是free -m,如:[[email protected] ~]# free -m           total  used  free shared buffers cached       Mem: 1024  1005  19   0    9    782

[转]观察进程的内存占用情况

转:http://www.cnblogs.com/bravery/archive/2012/06/27/2560611.html 概述 想必在linux上写过程序的同学都有分析进程占用多少内存的经历,或者被问到这样的问题--你的程序在运行时占用了多少内存(物理内存)?通常我们可以通过top命令查看进程占用了多少内存.这里我们可以看到VIRT.RES和SHR三个重要的指标,他们分别代表什么意思呢?这是本文需要跟大家一起探讨的问题.当然如果更加深入一点,你可能会问进程所占用的那些物理内存都用在了哪些

Linux 带宽、CPU、内存占用情况

iftop 查看带宽占用情况(总)yum install -y iftop 安装iftopnethogs 查看进程流量 curl http://218.5.73.233:8060/ip.php 查看出口ip 查看当前线程:ps -ef|grep javaps -ef|gerp com.meiya.main(包名) 1.CPU使用率情况命令:top 备注:用户占用CPU1.5%,系统占用CPU1.5%,空闲95.3%,其他占用1.7%:2.内存使用率情况命令:free -g 备注:内存总大小15G

Linux-进程内存占用情况

可以直接使用top命令后,查看%MEM的内容.可以选择按进程查看或者按用户查看,如想查看oracle用户的进程内存使用情况的话可以使用如下的命令: (1)top top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 可以直接使用top命令后,查看%MEM的内容.可以选择按进程查看或者按用户查看,如想查看oracle用户的进程内存使用情况的话可以使用如下的命令: $ top -u oracle 内容解释: PID:进程的ID USE