JVM内存分析以及Jconsole(一)

来源:互联网 发布:2015网络歌曲排行榜 编辑:程序博客网 时间:2024/06/05 16:53

JVM内存分析以及Jconsole

       最近在做的一个高校云平台项目慢慢接近了尾声,在功能慢慢完善的情况下我也抽时间来考量下自己代码的质量。刚好最近服务器Jboss三天内两次报了一个最常见也是最棘手的小问题:“java.lang.OutOfMemoryError: Java heap space ”;简直脑袋疼。

一:堆及GC机制

       Java 中内存分为四种:栈区,堆区,静态区,代码区。我们今天的主角当然是大家都非常熟悉的堆区---一般由程序员分配释放,存放由new创建的对象和数组,jvm不定时查看这个对象,如果没有引用指向这个对象就回收。

       Java的堆由Perm和Heap区组成,perm区是在JVM自己用的,用来存放类的信息等。它和Heap不同,运行期间GC不会释放空间。Heap区就是我们常说的堆。Heap区又分为yong和old区,具体如下图。

      

       每当我们NEW一个对象出来的时候都是存放在eden区。其中生命周期短的留在eden区,当eden区申请不到空间的时候,进行GC,把存活下来的对象拷贝到survior1.GC的时候eden中不能被垃圾回收的对象被放入到空的survivor2中,suvivor1中不能陪GC的对象也到survivor2中,这样始终保证一个survivor是空的。

       如果最后survivor都满了或者某个对象周期足够长,足够old则被拷贝到old区。

二:常见四种内存泄露

       内存泄露是指程序中间动态分配了内存,但在程序结束时没有释放这部分内存,从而造成那部分内存不可用的情况,重启计算机可以解决,但也有可能再次发生内存泄露,内存泄露和硬件没有关系,它是由软件设计缺陷引起的。 

 

1) 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。

2) 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。

3) 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。

4) 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。

三:内存是如何溢出的?

       我们可以用“淘金”来形象的描述下内存溢出的过程:

       从河里抽出来的沙子+金子+水被导入Eden(new出对象),当Eden满了之后进行淘沙(GC垃圾回收)将水过滤掉然后把沙子+金子转移到servivor中,然后当servivor满了之后进行深加工,精细挑选,(GC垃圾回收)把金子挑选出来放入old中。就这样不断的重复这样的过程,终于有一天Old被装满了,然后从servivor中转移过来的下一桶金就放不进Old只能从Old中溢出来-------啊~ 内存溢出了

 

0 0