内存泄露--概念如何?
内存泄露一般是存在于Jvm中的,那么JVM中常见的配置参数
? -Xms2048m,初始堆大小,建议<物理内存的1/4,默认值为物理内存的1/64 ? -Xmx2048m,最大堆大小,建议与-Xms保持一致,默认值为物理内存的1/4 ? -Xmn512m,新生代大小,建议不超过堆内存的1/2 ? -Xss256k,线程堆栈大小,建议256k ? -XX:+UseConcMarkSweepGC:开启CMS垃圾回收器z
这个配置一般也是在tomcat---bin---catalina.sh文件中设置的,列如:
首先明白一点:JVM的内存结构:栈内存、堆内存、永久代,但是其中的永久代在java8中就已经被元空间替代,并将元空间移除了JVM,所以目前的JVM就由栈内存和堆内存所构成
内存泄露一般为堆内存和元空间泄露,在java8之前是没有元空间的,是用永久代来表示,但是现在我们基本都是用的java8之后的版本,所以此文分析:内存泄露一般表达为:堆内存泄露和元空间泄露
此外,在堆内存泄露和元空间泄露,一般的泄露方式应该是堆内存,所以我们主要看堆内存
堆内存:
堆内存是JVM中内存空间最大的空间,所有的线程都会共用堆内存,其中堆内存中由新生代和老年代多构成,新生代又分为三个区域:eden,s0(from survivor),s1(to survivor)
所以堆内存=Eden+s0+s1+老年代
其中在堆内存中我们是存放的是数组以及内存对象的实例,比如:
新生代引发的GC为:YoungGC
老年代引发的GC为:FullGC
其中FullGC会引起整个的JVM的用户线程暂停,待垃圾回收完毕之后才能继续运行
堆内存中存在大量的对象,这些对象都有被引用,当所有对象占用空间达到堆内存的最大值,就会产生内存溢出,日志中还会报错:OutOfMemory:Java heap space
Jstat –gcutil pid 1000 100 Jmap –histo pid | head -20 Jmap –heap pidw
2、有问题到图,如图我们可以看到使用到堆越来越多,缓慢上升,并没有之前堆那种有增有减堆趋势
我们可以从上图看出来这个tps在缓慢的下降,持续压测的话应该为继续下降,甚至降低到0
通过上面我们已经知道了在我们压测过程中已经产生了内存泄露了,那么我们怎么来定位问题呢?
在上面的图中我们一般看的是,cn、com、org这些开头的,这些才是开发自己定义的,像java开头的还有int[]、byte[]等这些都是一些框架或者底层实现的
如果会自己看代码的话那就直接拿到源代码看看这些类中的代码,如果不会看那还是找下开发吧,哈哈
最后再附上一些查看Jvm运行状态的命令吧
监控jvm的GC情况 jstat -gcutil pid 1000 100 查看jvm配置信息 jmap -heap pid:可以看到java进程的堆的配置信息,各区的空间大小和配置信息 查看jvm中类和对象的占用情况 jmap -histo 5279 | head -20:查看jvm中各个类的实例数、占用内存数量以及类的全名 堆文件dump jmap -dump:format=b,file=m.hdump 17777:对堆内存进行dump,以文件的形式进行保存下 来,可以用jvisualvm等工具对文件进行分析
原文:https://www.cnblogs.com/Pycainiao/p/14606783.html