【JAVA虚拟机的内存分配】

内存分配

内存的自动管理的核心要点就是内存分配和内存自动回收。前几篇说了内存是怎么自动回收的,该篇说一下内存的分配

堆栈式内存

现在的虚拟机都是基于堆栈来管理内存的,内存分配主要是在堆上发生。所以研究这一阶段时,需要知道怎么设置一下虚拟机堆的大小。
虚拟机时通过虚拟机参数动态的来设定所有的参数大小。在IDEA中:
在这里插入图片描述找到这里,编辑程序的配置:
在这里插入图片描述简单说一下这几个参数的意思:
(1)-Xms:这个规定了虚拟机启动的时候堆的初始大小
(2)-Xmx:这个规定了虚拟机堆的最大size
(3)-Xmn:这个规定了堆内存中,新生代的内存大小。因为虚拟机内存一般是分代的,分为新生代和老年代,其中每个代内又有不同的分区。
(4)-XX:SurivivorRatio:这个规定了新生代中,Eden区和Surrvivor的比例,是8:1:1.这个后边会有体现。
(5)-XX PrintGCDetails:打印GC日志。
所以在这些参数的加持下,虚拟机的堆的大小是20M,不可拓展(因为最大也是20M),新生代10M,新生代里:Eden区8M,Surrvivor from:1M,Surrvivor to:1M.老年代:10M。
那么来一段代码:

public class Main {
    private static  final  int _1MB=1024*1024;
    public static void main(String[] args) {
        byte []a1,a2,a3,a4;
        a1=new byte[2*_1MB];
        a2=new byte[2*_1MB];
        a3=new byte[2*_1MB];
        a4=new byte[4*_1MB];
    }
}

可以看到GC输出:
在这里插入图片描述

首先解读一下这个GC的输出:
可以看到,堆的确被分为了两个代,PSYoungGen和ParOldGen.在新生代里又分为三个区:eden,from,to.老年代就一个对象区。这应证了之前的说法。
对象首先会被分配在Eden区:
对像首先会被分配在Eden区,因为Eden区的对象很多时候都是生命期很短,这个区的垃圾回收算法常常采用标记复制算法,因为需要复制的对象很少,大多都消亡了。
MinorGC:当Eden区的内存不够时,会发生一次MinorGC,这次GC会把Eden区的对象丢入Surrvivor区,但是在这个例子中,Surrvivor两个区都只有1M,无法存在对象,所以对象还是在Eden区,这也就是最后Eden区被占用了6M的原因。
大的对象会被丢入老年代:当分配到a4时,由于Eden区内部不足,MinorGC有没有回收到内存,所以这个4M的对象直接被分配在了Old区,不仅如此,就算是内存足够,一般来说大的对象也是会被默认的丢入老年代。比如:

public class Main {
    private static  final  int _1MB=1024*1024;
    public static void main(String[] args) {
        byte []a1,a2,a3,a4;
        a1=new byte[1*_1MB];
        a2=new byte[1*_1MB];
        a3=new byte[1*_1MB];
        a4=new byte[4*_1MB];
    }
}

这个Eden区时足够的,但是看一下输出:
在这里插入图片描述
依然是在Old区,因为大的对象一般都会被丢入Old区,Old区的垃圾回收算采用的是标记整理,这样做为了避免大的对象在新生代一直被复制,因为新生代采用的是标记复制算法搜集垃圾。
MajorGC:发生在老年代的GC,这是一个十分很慢的过程,一般来说比Minor GC慢了10倍。也叫FULL GC。
-XX:PretenureSizeThreshold:这个参数其实是设置了一个阈值,大于这个参数的都会被分配到老年代,但是也不是绝对的。如果仅仅是大了几十个字节,大概率是老年代和新生代都会存在一点。
在这里插入图片描述
这个参数不能直接写3M,要直接指定数值。

年龄的增加

Minor GC其实是非常频繁的,在新生代的对象每经过一次Minor GC年龄就会加一,当年龄增加到一定年纪的时候(默认是15岁)。通过参数:MaxTenuringThrehold来指定。

动态年龄判断

为了更好的利用内存,对象被丢入到老年代的时机也不是固定不变的,如果Survivor对象的大小大于了该区内存的一半,那么年龄大于或者等于这个该对象的所有对象可以不进入Survivor区,直接进入老年区。

空间分配担保

在Minor GC之前,虚拟机会检查老年代的最大连续空间是不是大于当前新生代所有对象空间的总和(因为新生代可能全部一次进入老年代),如果可行就进行Minor GC,否则,额,还是会按照一定概率进行GC,是要检查某个参数的状态,记得不是很清楚了,留个坑待补。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值