java内存分配具体分析

对象内存分配流程图

在这里插入图片描述

验证对象是否栈上分配

/**
 * 栈上分配,标量替换
 * 代码调用了1亿次alloc(),如果是分配到堆上,大概需要1GB以上堆空间,如果堆空间小于该值,必然会触发GC。
 * 
 * 使用如下参数不会发生GC
 * -Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:+EliminateAllocations
 * 使用如下参数都会发生大量GC
 * -Xmx15m -Xms15m -XX:-DoEscapeAnalysis -XX:+PrintGC -XX:+EliminateAllocations
 * -Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-EliminateAllocations
 */
public class AllotOnStack {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            alloc();
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    private static void alloc() {
        User user = new User();
        user.setNum(1);
        user.setUuid("lcf");
    }
}

图1-1

图1-2
图1-3

对象在堆内存的分配的情况

通过下图可以看到类在运行过程中,会将对象存在eden区,eden区在内存未满的情况下,并不会进行minor gc。图中eden区内存占用了87%
在这里插入图片描述

下图中可以看到,在eden区未满的情况下,新进来的对选哪个会持续向eden区加入对象。
在这里插入图片描述

下图因为eden区满了之后,Eden区没有足够空间进行分配时,虚拟机将发起一次MinorGC,GC期间虚拟机又发现allocation2无法存入Survior空间,所以只好把新生代的对象提前转移到老年代中去,老年代上的空间足够存放allocation2,所以不会出现FullGC。
在这里插入图片描述
下图执行MinorGC后,后面分配的对象如果能够存在eden区的话,还是会在eden区分配内存。 将存活的对象分别移动到survivor和老年代。
在这里插入图片描述

下图通过设置jvm参数-XX:PretenureSizeThreshold=1000000 (单位是字节) -XX:+UseSerialGC,可以使大于1000000 字节的对象直接进入老年代。
好处是可以使存活在年期带的大对象不需要在eden和survivor来回移动进行gc,从而消耗性能。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值