进程内存分析

分析工具

jprofiler
mat 2 : eclipse memory analyzer

JDK 内置工具

https://blog.csdn.net/fenglibing/article/details/6411940

java 计算内存大小的工具

https://www.jianshu.com/p/9d729c9c94c4

dump 出进程内存

https://blog.csdn.net/renfufei/article/details/41444559
/opt/taobao/java/bin/jmap -dump:file=/tmp/1.bin,format=b pid
如果报:Unable to open socket file: target process not responding or HotSpot VM not loaded
则在前面加:sudo -u USERID (即进程的用户名)
公有云上用的:
sudo -u admin /opt/taobao/java/bin/jmap -dump:format=b,file=/tmp/%s/%s.bin %s
mac 上:
jmap -dump:format=b,file=/Users/shicai.xsc/Downloads/bin/10.bin 44005

IDEA debug 时分析内存

https://www.jetbrains.com/help/idea/analyze-objects-in-the-jvm-heap.html

dump 出内存文件后,mat 打开发现内存占用比线上使用的少

https://stackoverflow.com/questions/32271731/why-is-my-java-heap-dump-size-much-smaller-than-used-memory
When dumping its heap, the JVM will first run a garbage collection cycle to free any unreachable objects.
因为:dump 时会先做一次内存回收。

jhat

用途:是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言

生成tomcat.bin dump文件后,使用jhat查看

root@blue-pc:/home/blue/apache-tomcat-7.0.39/conf# jhat tomcat.bin
.....
Started HTTP server on port 7000
Server is ready.

有时你dump出来的堆很大,在启动时会报堆空间不足的错误,可以使用如下参数:
jhat -J-Xmx512m heap.bin

shallow heap 和 retained heap 区别

https://blog.csdn.net/a740169405/article/details/53610689

换句话说,Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。 不过,释放的时候还要排除被GC Roots直接或间接引用的对象。他们暂时不会被被当做Garbage。

jstat -gc 和 gc.log 中关于 Full GC 的数目不一致

https://blog.csdn.net/caomiao2006/article/details/47780765

MAT

  • 使用的 tips

这个讲得非常好
https://eclipsesource.com/blogs/2013/01/21/10-tips-for-using-the-eclipse-memory-analyzer/
https://www.jianshu.com/p/759e02c1feee

  • 用少内存来分析很大的 heap 文件

https://www.techpaste.com/2015/07/how-to-analyse-large-heap-dumps/

主要是给 MAT 的 MemoryAnalyzer.ini (Applications/mat%202.app/Contents/Eclipse/ 内)加上下面配置

-Xms6144m
-Xmx8192m
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:+CMSClassUnloadingEnabled
-XX:+UseCMSInitiatingOccupancyOnly

  • 查询变量值

select * from com.alibaba.cobar.net.handler.FrontendAuthenticator
select * from com.alibaba.cobar.config.UserConfig where (toString(name)="MEEGIRLCLOUDADMIN_DAILY_APP") 
或者在 Histogram 页面中查询

  • 通过 dominator_tree 找到最耗内存的线程

  • 通过 thread_overview 找到线程调用栈

找出其中哪一个步骤耗费资源最多,以及当时的栈数据

Full GC

Full GC (Ergonomics)

https://blog.csdn.net/wwd0501/article/details/91465679

Full GC (Ergonomics)
2021-06-12T14:02:45.526+0800: 700.948: [Full GC (Ergonomics) [PSYoungGen: 65536K->65535K(98304K)] [ParOldGen: 131050K->131050K(131072K)] 196586K->196586K(229376K), [Metaspace: 76621K->76621K(1118208K)], 0.2264659 secs] [Times: user=1.10 sys=0.00, real=0.23 secs]

  1. 老年代内存使用达到极限。当发生几次Full GC后,老年代空间的内存使用仍然达到其容量极限时,我们可以知道老年代空间已经成为应用的瓶颈了。这可能是由于老年代空间分配不足,或者应用发生了内存泄漏。

默认的,新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 ),即:新生代 ( Young ) = 1/3 的堆空间大小。老年代 ( Old ) = 2/3 的堆空间大小。其中,新生代 ( Young ) 被细分为 Eden 和 两个 Survivor 区域,这两个 Survivor 区域分别被命名为 from 和 to,以示区分。

Full GC (Metadata GC Threshold)

https://blog.csdn.net/liubenlong007/article/details/78143285

2021-06-12T14:05:35.361+0800: 21.414: [Full GC (Metadata GC Threshold) [PSYoungGen: 24091K->0K(786432K)] [ParOldGen: 48045K->58688K(1048576K)] 72137K->58688K(1835008K), [Metaspace: 57670K->57670K(1099776K)], 0.1733414 secs] [Times: user=0.90 sys=0.01, real=0.17 secs]

-XX:MetaspaceSize=128M

各种 jvm 参数

https://www.cnblogs.com/easonjim/p/7490114.html

  • -XX:PermSize=64M:JVM初始分配的非堆内存
  • -XX:MaxPermSize=128M:JVM最大允许分配的非堆内存,按需分配

VM内存管理的机制:

1、堆(Heap)和非堆(Non-heap)内存

按照官方的说法:“Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在Java虚拟机启动时创建的。”,“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。

可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。 

Metaspacesize  MaxPermSize 区别

https://www.jianshu.com/p/b448c21d2e71

https://www.cnblogs.com/dennyzhangdd/p/6770188.html

JDK8+移除了Perm,引入了Metapsace,它们两者的区别是什么呢?Metasace上面已经总结了,无论-XX:MetaspaceSize-XX:MaxMetaspaceSize两个参数如何设置,随着类加载越来越多不断扩容调整,直到MetaspaceSize(如果没有配置就是默认20.8m)触发FGC,上限是-XX:MaxMetaspaceSize,默认是几乎无穷大。而Perm的话,我们通过配置-XX:PermSize以及-XX:MaxPermSize来控制这块内存的大小,jvm在启动的时候会根据-XX:PermSize初始化分配一块连续的内存块,这样的话,如果-XX:PermSize设置过大,就是一种赤果果的浪费。很明显,Metapsace比Perm好多了^^;

JDK7 Perm 验证如下--设置-XX:PermSize=64m -XX:MaxPermSize=64m,那么PC初始化就是64m:

jdk8中:

1.字符串常量由永久代转移到堆中。

2.持久代已不存在,PermSize MaxPermSize参数已移除。(看图中最后两行)

1.MetaspaceSize

初始化的Metaspace大小,控制元空间发生GC的阈值。GC后,动态增加或降低MetaspaceSize。在默认情况下,这个值大小根据不同的平台在12M到20M浮动。使用Java -XX:+PrintFlagsInitial命令查看本机的初始化参数

2.MaxMetaspaceSize

限制Metaspace增长的上限,防止因为某些情况导致Metaspace无限的使用本地内存,影响到其他程序。在本机上该参数的默认值为4294967295B(大约4096MB)。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值