zoukankan      html  css  js  c++  java
  • JVM(3) 之 内存分配与回收策略

    之前讲过虚拟机中的堆,他是整个内存模型中占用最大的一部分,而且不是连续的。当有需要分配内存的时候,一般有两个方法分配,指针碰撞和空闲列表。该部分的内存回收是由虚拟机的垃圾收集器GC进行管理的。 
      刚刚粗略的回忆了上一博文所讲的内容,而这一章我们的重点还在堆上面。之前有简单的提到过新生代和老年代,今天就给大家好好梳理下这部分。 
      堆是存放对象以及数组的区域,但不是胡乱的有空间就分配的内存。堆在内存中分为了年轻代、年老代。 
      我们先看看年轻代,这个区域又被分为了一个Eden和两个Survivor区,即伊甸园和存活区。看一张图: 
    这里写图片描述 
      从图中可以清楚的看到他们的关系是8:1。那为什么Eden占用这么多呢?因为对象都会在Eden区创建。每次只使用Eden区和一个Survivor区,当这两个区满了之后就会将还存活的对象复制到另一个空白区(MINOR GC),大家是不是在想那空间怎么会够用呢?其实年轻代的对象有98%都是朝生夕死的,所以根本不用担心不够用,这也是为什么比例是8:1而不是1:1的原因。而且!就算是不够用,我们不是还有年老代吗! 
      我们暂且先不说年老代,还有个问题没有解决,刚刚我们提到了复制,所以这里我们抱着求知的欲望来讲讲是怎么个复制法。首先看图: 
    这里写图片描述 
      图中分为了两个部分,每次只使用其中的一部分(这里不是完全按照刚刚伊甸园和空白区的占用比例来讲,可以理解为通用版)。当这部分满了后,就会将还存活的复制到另一个区,再将这个区清空,如图: 
    这里写图片描述 
      但这种方法也有弊端,就是会浪费了一半的内存空间。但是对于年轻代这种朝生夕死的特征是一个很好的解决方法,因为只要对一半的空间进行操作,把范围大大的缩小了。 
      对于年老区域,刚刚也说了,如果年轻代不够放了就放在年老代,还有一种情况就是对象在年轻代中存活的太久了,就会放到年老区,就像人的岁数大了就会变老年人,对象在年轻代也有岁数:每当进行一次复制回收的时候,还在年轻代中存活的对象就会加1岁,默认15岁后就到年老代。可以通过-XX:MaxTenuringThreshold=15来设置多少岁后进入年老区。 
      年老和永久区垃圾收集的方法都是“标记-清除-整理”,看图: 
    这里写图片描述 
      这里如果还使用年轻代的回收方法的话肯定不适用了,那边的特性是朝生夕死,而年老代存活的一般是大对象或者很难死去的对象(回收),所以不符合条件。当年老代内存不足的话就会触发垃圾收集,这个回收叫做FULL GC.默认是占用了68%后收集,可用参数-XX:CMSInitiatingOccupancyFraction=68自行设置。 
      收集方法中的标记这里先不说,标记好了就清除掉,最后整理成逻辑连续的区域。最后的结果: 
    这里写图片描述 
      这样可以有效的避免了内存碎片。 

  • 相关阅读:
    [ Algorithm ] N次方算法 N Square 动态规划解决
    [ Algorithm ] LCS 算法 动态规划解决
    sql server全文索引使用中的小坑
    关于join时显示no join predicate的那点事
    使用scvmm 2012的动态优化管理群集资源
    附加数据库后无法创建发布,error 2812 解决
    浅谈Virtual Machine Manager(SCVMM 2012) cluster 过载状态检测算法
    windows 2012 r2下安装sharepoint 2013错误解决
    sql server 2012 数据引擎任务调度算法解析(下)
    sql server 2012 数据引擎任务调度算法解析(上)
  • 原文地址:https://www.cnblogs.com/itommy/p/10644587.html
Copyright © 2011-2022 走看看