java 新生代内存分配题_jvm 内存分配

java堆内存概述

Java 的自动内存管理主要是针对对象内存的回收和对象内存的分配。同时,Java 自动内存管理最核心的功能是 堆 内存中对象的分配与回收。

Java 堆是垃圾收集器管理的主要区域,因此也被称作GC 堆(Garbage Collected Heap).从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代:再细致一点有:Eden 空间、From Survivor、To Survivor 空间等。进一步划分的目的是更好地回收内存,或者更快地分配内存。

一般情况下:新生代:老年代 比例为 1:3

而对于新生代代来说:Eden:From:to为8:1:1

f4b0577b233e2977fa10e34c40bc5aab.png

常见的分配策略:

85017956596c34c39190f9156a33c10a.png

对象优先在 eden 区分配

目前主流的垃圾收集器都会采用分代回收算法,因此需要将堆内存分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。

大多数情况下,对象在新生代中 eden 区分配。当 eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC.下面我们来进行实际测试以下。

在测试之前我们先来看看 Minor GC 和 Full GC 有什么不同呢?

新生代 GC(Minor GC):指发生新生代的的垃圾收集动作,Minor GC 非常频繁,回收速度一般也比较快。

老年代 GC(Major GC/Full GC:指发生在老年代的 GC,出现了 Major GC 经常会伴随至少一次的 Minor GC(并非绝对),Major GC 的速度一般会比 Minor GC 的慢 10 倍以上。

测试

3cbe8521d9fd2d73a27b4d8ff4f1fe83.png

运行结果:

b98705ec72a61fc17ef60c4c7cb10c78.png

从上图我们可以看出 eden 区内存几乎已经被分配完全(即使程序什么也不做,新生代也会使用 2000 多 k 内存)。假如我们再为 allocation2 分配内存会出现什么情况呢?

3d00df0fcb5c906d3bb8bdbb73592593.png

运行结果:

2c6adda2c30f140b1c415d198207b0e1.png

简单解释一下为什么会出现这种情况: 因为给 allocation2 分配内存的时候 eden 区内存几乎已经被分配完了,我们刚刚讲了当 Eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC.GC 期间虚拟机又发现 allocation1 无法存入 Survivor 空间,所以只好通过 分配担保机制 把新生代的对象提前转移到老年代中去,老年代上的空间足够存放 allocation1,所以不会出现 Full GC。执行 Minor GC 后,后面分配的对象如果能够存在 eden 区的话,还是会在 eden 区分配内存。

大对象直接进入老年代

配置4M以上的对象为大对象.

启动参数:

-verbose:gc -XX:+PrintGCDetails 开启GC日志打印

-Xms20 M 设置JVM初始内存为20M

-Xmx20 M 设置JVM最大内存为20M

-Xmn10 M 设置年轻代内存大小为10M

XX: PretenureSizeThreshold 参数,令大于这个设置值的对象直接在老年代分配。这样做的目的是避免在 Eden 区及两个 Survivor 区之间发生大量的内存复制,设置超过改大小的为大对象

测试小于3M的对象:

dac7557aa762901e6c33efaae3cd8482.png

运行结果:

79391b12c81c0cd84344ee1f2730e62c.png

上图看出是直接分配在新生代中的。

测试大于3M的大对象

78a056e8940917016e68dfce3971c0cf.png

当大于3M时,会分配在老年代内存上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值