• 高内存分析


    1、查看哪些应用占用内存比较大:

    查看哪几个进程内存占用最高:top -c,输入大写M,以内存使用率从高到低排序

    PID : 进程id
    PPID : 父进程id
    RUSER : Real user name
    UID : 进程所有者的用户id
    USER : 进程所有者的用户名
    GROUP : 进程所有者的组名
    TTY : 启动进程的终端名。不是从终端启动的进程则显示为 ?
    PR : 优先级
    NI : nice值。负值表示高优先级,正值表示低优先级
    P : 最后使用的CPU,仅在多CPU环境下有意义
    %CPU : 上次更新到现在的CPU时间占用百分比
    TIME : 进程使用的CPU时间总计,单位秒
    TIME+ : 进程使用的CPU时间总计,单位1/100秒
    %MEM : 进程使用的物理内存百分比
    VIRT : 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
    SWAP : 进程使用的虚拟内存中,被换出的大小,单位kb。
    RES : 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
    CODE : 可执行代码占用的物理内存大小,单位kb
    DATA : 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
    SHR : 共享内存大小,单位kb
    nFLT : 页面错误次数
    nDRT : 最后一次写入到现在,被修改过的页面数。
    S : 进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
    COMMAND : 命令名/命令行
    WCHAN : 若该进程在睡眠,则显示睡眠中的系统函数名
    Flags : 任务标志,参考 sched.h
    
    默认情况下仅显示比较重要的 PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND 列。可以通过下面的快捷键来更改显示内容。 更改显示内容
    通过 f 键可以选择显示的内容。按 f 键之后会显示列的列表,按 a-z 即可显示或隐藏对应的列,最后按回车键确定。
    按 o 键可以改变列的显示顺序。按小写的 a-z 可以将相应的列向右移动,而大写的 A-Z 可以将相应的列向左移动。最后按回车键确定。
    按大写的 F 或 O 键,然后按 a-z 可以将进程按照相应的列进行排序。而大写的 R 键可以将当前的排序倒转
    

      

    2、通过jmap -heap 进程id 命令排除是由于堆分配内存问题:

    Attaching to process ID 542287, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.20-b23
    
    using thread-local object allocation.
    Garbage-First (G1) GC with 43 thread(s)
    //堆配置信息
    Heap Configuration:
       //指定 jvm heap 在使用率小于 n 的情况下 ,heap 进行收缩 ,Xmx==Xms 的情况下无效 , 如 
       MinHeapFreeRatio         = 40
       //指定 jvm heap 在使用率大于 n 的情况下 ,heap 进行扩张 ,Xmx==Xms 的情况下无效 , 如 
       MaxHeapFreeRatio         = 70
       //最大堆空间
       MaxHeapSize              = 5393874944 (5144.0MB)
       //设置Yong Generation的初始值大小,一般情况下,不允许-XX:Newratio值小于1,即Old要比Yong大。
       NewSize                  = 1363144 (1.2999954223632812MB)
       //设置Yong Generation的最大值大小
       MaxNewSize               = 3235905536 (3086.0MB)
       OldSize                  = 5452592 (5.1999969482421875MB)
       //设置年轻代和老年代的比例,默认情况下,此选项为2
       NewRatio                 = 2
       //默认eden空间大小和survivor空间大小的比,默认情况下为8
       SurvivorRatio            = 8
       //初始化元空间大小,控制gc阀值,gc后动态增加或者降低元空间大小,默认情况下平台的不同,步长为12-20M
       MetaspaceSize            = 209715200 (200.0MB)
       //默认1G,这个参数主要是设置Klass Metaspace的大小,不过这个参数设置了也不一定起作用,前提是能开启压缩指针,假如-Xmx超过了32G,压缩指针是开启不来的。如果有Klass Metaspace,那这块内存是和Heap连着的。
       CompressedClassSpaceSize = 1073741824 (1024.0MB)
       //为类元数据分配的最大空间量
       MaxMetaspaceSize         = 536870912 (512.0MB)
       //堆内存中一个Region的大小可以通过-XX:G1HeapRegionSize参数指定,大小区间只能是1M、2M、4M、8M、16M和32M,总之是2的幂次方,如果G1HeapRegionSize为默认值,则在堆初始化时计算Region的实践大小
       G1HeapRegionSize         = 2097152 (2.0MB)
    //堆的使用信息
    Heap Usage:
    G1 Heap:
    //区域数量
       regions  = 2572
    //堆内存大小
       capacity = 5393874944 (5144.0MB)
    //已经使用了
       used     = 3216639400 (3067.62638092041MB)
    //空闲着的堆内存
       free     = 2177235544 (2076.37361907959MB)
       59.63503850933923% used
    以下同理
    G1 Young Generation:
    Eden Space:
       regions  = 425
       capacity = 2650800128 (2528.0MB)
       used     = 891289600 (850.0MB)
       free     = 1759510528 (1678.0MB)
       33.62341772151899% used
    Survivor Space:
       regions  = 1
       capacity = 2097152 (2.0MB)
       used     = 2097152 (2.0MB)
       free     = 0 (0.0MB)
       100.0% used
    G1 Old Generation:
       regions  = 1109
       capacity = 2740977664 (2614.0MB)
       used     = 2323252648 (2215.62638092041MB)
       free     = 417725016 (398.37361907958984MB)
       84.75999927009985% used
    
    35394 interned Strings occupying 3871104 bytes.
    

      

    3、找到最耗内存的对象
    jmap -histo 进程ID(带上:live则表示先进行一次FGC再统计,如jmap -histo:live 进程ID)

    4、导出内存转储快照dump文件:
    4.1、通过java进程命令定位 系统进程并使用jmap工具dump文件。

    ps -ef | grep java
    生成dump文件的命令:
    jmap -dump:format=b,file=20181218.dump 16048
    file后面的是自定义的文件名,最后的数字是进程的pid。
    1
    2
    3
    4
    4.2、使用jvisualvm来分析dump文件:

    4.5、线程当前的状态是我们主要关注的内容。
    dump文件中描述的线程状态

    runnable:运行中状态,在虚拟机内部执行,可能已经获取到了锁,可以观察是否有locked字样。
    blocked:被阻塞并等待锁的释放。
    wating:处于等待状态,等待特定的操作被唤醒,一般停留在park(), wait(), sleep(),join() 等语句里。
    time_wating:有时限的等待另一个线程的特定操作。
    terminated:线程已经退出

    4.6、进程的区域划分

    进入区(Entry Set):等待获取对象锁,一旦对象锁释放,立即参与竞争。
    拥有区(The Owner):已经获取到锁。
    等待区(Wait Set):表示线程通过wait方法释放了对象锁,并在等待区等待被唤醒。

    4.7、方法调用修饰

    locked: 成功获取锁
    waiting to lock:还未获取到锁,在进入去等待;
    waiting on:获取到锁之后,又释放锁,在等待区等待;

    4.8、OQL(对象查询语言)
    如果需要根据某些条件来过滤或查询堆的对象,比如现在我们查询下系统中类加载器一共有几种?


    8、.用jstack查看一下
    jstack pid | grep tid(线程ID) -A 30

  • 相关阅读:
    跑步前后吃什么?
    英雄杀八人场心得
    如何判断JavaScript数据具体类型
    js实现时间日期的格式化
    各个公司前端笔试题回顾
    原型模式Prototype,constructor,__proto__详解
    二级菜单不同方法的实现
    秋招笔试碰到的疑难题目1
    php和mysql学习问题笔记
    es6学习笔记12--Class
  • 原文地址:https://www.cnblogs.com/SunshineKimi/p/14608057.html
Copyright © 2020-2023  润新知