本系列笔记主要基于《深入理解Java虚拟机:JVM高级特性与最佳实践 第2版》,是这本书的读书笔记。

内存分配一般关注的是对象在堆上分配的情况,对象主要分配在新生代的Eden区中,如果启用了本地线程分配缓冲,将按线程优先在TLAB上分配。少数情况下也会直接分配在老年代中,这取决于使用的垃圾收集器组合,以及设置的JVM参数。

对象优先在Eden分配

大多数情况下,对象在Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机会发起一次Minor GC。

  • Minor GC:发生在新生代的垃圾收集,因为一般大多对象具有朝生夕灭的特性,所以Minor GC发生非常频繁,回收速度也比较快。
  • Major GC/Full GC:发生在老年代的垃圾收集,发生了Major GC,Major GC的回收速度比较慢。

当Minor GC时,发现Eden中已存在的对象,也无法放入Survivor区,那么就会通过分配担保机制提前转移到老年代。

大对象直接进入老年代

大对象一般是指需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串或数组,例如new byte[10 * 1024 * 1024]是一个10M的大对象。遇到大对象对虚拟机来说是可怕的,更可怕的是遇到一群朝生夕灭的短命大对象。经常遇到大对象,会导致在内存还有不少空间时就提前触发垃圾收集,用以获取足够的连续内存空间来安置大对象。

虚拟机提供了一个参数-XX:PretenureSizeThreshold,大于这个参数的对象会直接在老年代分配。这样能避免在Eden区和两个Survivor区之间大量的内存复制(新生代采用复制算法)。

长期存活的对象进入老年代

虚拟机采用了分代收集的思想来回收内存,既然这样,那内存回收时,虚拟机需要能识别哪些对象应该放到新生代,哪些对象应该放到老年代。为了做到这点,虚拟机给每个对象定义了一个对象年龄计数器。

如果对象在Eden区出生后经过一次Minor GC仍然存活,并且能被Survivor区容纳的话,那么对象将被移动到Survivor空间,同时对象年龄设为1。对象在Survivor区中每熬过一次Minor GC,对象年龄就增加1岁。当对象年龄达到一定值后(默认15),对象就会晋升到老年代中。这个晋升到老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold设置。

动态对象年龄判定

有时为了适应不同的内存情况,虚拟机并不是死板的按照-XX:MaxTenuringThreshold的值,要求对象必须达到年龄阈值才能晋升老年代。

如果在Survivor空间中,所有相同年龄的对象的大小总和,大于Survivor空间的一半,那么年龄大于或等于该年龄的对象,都可以直接进入老年代,无须等到-XX:MaxTenuringThreshold设置的年龄阈值。

空间分配担保

新生代采用了复制收集算法,为了提高内存利用率,通常将新生代划分为了1个Eden区,和2个相同大小的Survivor区,它们的大小比例是8:1:1。这样其中的一个Survivor区来作为轮换备份,当出现大量对象在Minor GC后仍然存活时(极端情况例如所有对象都存活),Survivor区无法容纳,这时就需要老年代进行分配担保,将Survivor无法容纳的对象直接进入老年代。

老年代进行这样的分配担保,前提是老年代本身还有容纳这些对象的剩余空间。而有多少对象能存活下来在内存回收之前是无法准确预知的,所以只好根据之前每次回收晋升到老年代对象容量的平均大小,作为经验值,与老年代剩余空间进行比较。如果经验值大于剩余空间,这时老年代空间不足,就会发起一次Full GC。如果经验值小于剩余空间,就会Minor GC,这时新生代内存回收实际发生后,如果晋升到老年代时老年代空间不足,就会担保失败,担保失败则会再发起Full GC。

可见,担保失败后再Full GC,绕的圈子是最大的。按照现在分配担保的规则,只要老年代的连续空间大于新生代对象总大小,或历次晋升的平均大小,就会进行Minor GC,否则进行Full GC。

JVM探秘:内存分配与回收策略的更多相关文章

  1. JVM的内存分配垃圾回收策略

    之前看过<深入了解Java虚拟机>感觉容易忘,今天写一篇博客加深一下印象. JVM的内存分配和垃圾回收(GC)主要发生在Java堆中.而Java堆根据对象的存活时间可以分为新生代和老年代, ...

  2. JVM的内存分配和回收策略

    对象的Class加载 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载.解析和初始化过.如果没有,那必须先执行相应 ...

  3. JVM:内存分配与回收策略

    Java技术体系中所提倡的自动内存管理最终可以归结为自动化的解决了两个问题:给对象分配内存以及回收分配给对象的内存. 对象的内存分配,往大方向讲,就是在堆上分配(但也可能经过JIT编译后被拆散为标量类 ...

  4. jvm之内存分配与回收策略

    1.java堆中各代分布 (1)Young:主要是用来存放新生的对象. (2)Old:主要存放应用程序中生命周期长的内存对象. (3)Permanent:是指内存的永久保存区域,主要存放Class和M ...

  5. Java虚拟机垃圾回收:内存分配与回收策略 方法区垃圾回收 以及 JVM垃圾回收的调优方法

    在<Java对象在Java虚拟机中的创建过程>了解到对象创建的内存分配,在<Java内存区域 JVM运行时数据区>中了解到各数据区有些什么特点.以及相关参数的调整,在<J ...

  6. JVM垃圾回收器、内存分配与回收策略

    新生代垃圾收集器 1. Serial收集器 serial收集器即串行收集器,是一个单线程收集器. 串行收集器在进行垃圾回收时只使用一个CPU或一条收集线程去完成垃圾回收工作,并且会暂停其他的工作线程( ...

  7. JVM学习十 -(复习)内存分配与回收策略

    内存分配与回收策略 对象的内存分配,就是在堆上分配(也可能经过 JIT 编译后被拆散为标量类型并间接在栈上分配),对象主要分配在新生代的 Eden 区上,少数情况下可能直接分配在老年代,分配规则不固定 ...

  8. Java虚拟机内存分配与回收策略

    内存分配与回收策略 Minor GC 和 Full GC Minor GC:发生在新生代上,因为新生代对象存活时间很短,因此 Minor GC 会频繁执行, 执行的速度一般也会比较快. Full GC ...

  9. jvm内存分配和回收策略

    在上一篇中,已经介绍了内存结构是什么样的. 这篇来介绍一下 内存是怎么分配的,和怎么回收的.(基本取自<深入理解Java虚拟机>一书) java技术体系中所提倡的自动内存管理最终可以归结为 ...

随机推荐

  1. [全+转载] solaris 网络配置

    ===================== 较为重要的几个文件: /etc/nodename                      主机名(即 hostname命令的输出) /etc/defaul ...

  2. Codeforces Round #200 (Div. 1 + Div. 2)

    A. Magnets 模拟. B. Simple Molecules 设12.13.23边的条数,列出三个等式,解即可. C. Rational Resistance 题目每次扩展的电阻之一是1Ω的, ...

  3. H3C 单区域OSPF配置示例一(续)

  4. 【codeforces 761C】Dasha and Password(动态规划做法)

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  5. Django入门5--URL传递参数

  6. linux中添加常用应用程序的桌面图标

    在网上随处可以找到怎么样把应用程序的图标放到桌面上,我刚用ubuntu时也是按照网上的做法,一步一步的做的,现将网上的做法复制下来: 桌面配置文件简述\label{sec:desktop file} ...

  7. 2018-2-13-WPF-拖动时出现-Invalid-FORMATETC-structure

    title author date CreateTime categories WPF 拖动时出现 Invalid FORMATETC structure lindexi 2018-2-13 17:2 ...

  8. 多校 HDU - 6614 AND Minimum Spanning Tree (二进制)

    传送门 AND Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 ...

  9. 2018-9-14-win10-UWP-标题栏后退

    title author date CreateTime categories win10 UWP 标题栏后退 lindexi 2018-9-14 20:22:8 +0800 2018-2-13 17 ...

  10. 牛客小白月赛15A 斑羚飞渡

    链接:https://ac.nowcoder.com/acm/contest/917/A 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言262144K 64b ...