Java内存模型以及gc算法

1.java内存模型

  •   JVM堆内存分为2块:Permanent Space 和 Heap Space。
  •   Permanent 即 持久代(Permanent Generation),主要存放的是Java类定义信息,与垃圾收集器要收集的Java对象关系不大。持久代 用于存放类信息,静态类型数据,final修饰的变量,常量,方法,如 Java Class, Method 等。持久代对垃圾回收没有显著影响。但是有些应用可能动态生成或调用一些Class。方法区都保存在持久代。
  •   Heap = { Old + NEW = {Eden, from, to} },Old 即 年老代(Old Generation),New 即 年轻代(Young Generation)。年老代和年轻代的划分对垃圾收集影响比较大。

1)年轻代: 所有新生成的对象首先都是放在年轻代。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。因为需要交换的原因,Survivor区至少有一个是空的。

2)年老代: 在年轻代中经历了N次(可配置)垃圾回收后仍然存活的对象,就会被复制到年老代中。

  •   当一组对象生成时,内存申请过程如下:

1).JVM会试图为相关Java对象在年轻代的Eden区中初始化一块内存区域。

2).当Eden区空间足够时,内存申请结束。否则执行下一步。

3).JVM试图释放在Eden区中所有不活跃的对象(Young GC)。释放后若Eden空间仍然不足以放入新对象,JVM则试图将部分Eden区中活跃对象放入Survivor区。

4).Survivor区被用来作为Eden区及年老代的中间交换区域。当年老代空间足够时,Survivor区中存活了一定次数的对象会被移到年老代。

5).当年老代空间不够时,JVM会在年老代进行完全的垃圾回收(Full GC)。

6).Full GC后,若Survivor区及年老代仍然无法存放从Eden区复制过来的对象,则会导致JVM无法在Eden区为新生成的对象申请内存,即出现“Out of Memory”。

《Java内存模型以及gc算法》

图片来源:http://www.cnblogs.com/kabi/p/5171406.html

2.“Out of Memory”原因

OOM(“Out of Memory”)异常一般主要有如下2种原因:

  •  年老代溢出,表现为:java.lang.OutOfMemoryError:Javaheapspace。这是最常见的情况,产生的原因可能是:

设置的内存参数Xmx过小或程序的内存泄露及使用不当问题。例如循环上万次的字符串处理、创建上千万个对象、在一段代码内申请上百M甚至上G的内存。还有的时候虽然不会报内存溢出,却会使系统不间断的垃圾回收,也无法处理其它请求。这种情况下除了检查程序、打印堆内存等方法排查,还可以借助一些内存分析工具,比如MAT就很不错。

  •   持久代溢出,表现为:java.lang.OutOfMemoryError:PermGenspace。

通常由于持久代设置过小,动态加载了大量Java类而导致溢出 ,解决办法唯有将参数 -XX:MaxPermSize 调大(一般256m能满足绝大多数应用程序需求)。将部分Java类放到容器共享区(例如Tomcat share lib)去加载的办法也是一个思路,但前提是容器里部署了多个应用,且这些应用有大量的共享类库。

3.gc类型

  • Minor gc:发生在Eden区空间不足时,会导致应用程序的线程短暂的暂停。在Eden这里使用空闲指针来指着最后一个被分配的对象,每次要求分配空间时,先判断空闲指针在Eden的位置,判断是否有足够内存来分配。若不够,则进行Copying算法,jvm将Eden的存活对象Copy到Survivor区,最后让Eden清空。
  • Major gc/Full gc:发生在Eden区或者Survivor的对象要求放入年老区,年老区空间不足。此时采用标记(Mark)算法,将所有对象(所有区)扫描一次,标记存活的对象,然后回收未标记的对象。接着对剩下的空间要么进行合并(compact),要么标记出来便于下次分配。

4.gc中判断对象是否存活的算法

  • 引用计数法:给对象增加一个引用计数器,有引用指向它时就加1,引用失效时就减1。当计数器为0时,表示该对象失效。(但可能会出现循环引用的问题,导致对象无法释放)
  • 根搜索法:通过一系列“GCRoots”的对象为起点,从这些节点往下搜索,经过的路径成为引用链。当一个对象不在任何一条引用链上时,该对象失效。

更详细资料可以参考:http://www.cnblogs.com/hzzjj/p/6268432.html

    原文作者:java内存模型
    原文地址: https://blog.csdn.net/learner_and_thinker/article/details/78019227
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞