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

guanbin-529      2022-06-04     187

关键词:

内存分配与回收策略

对象的内存分配,就是在堆上分配(也可能经过 JIT 编译后被拆散为标量类型并间接在栈上分配),对象主要分配在新生代的 Eden 区上,少数情况下可能直接分配在老年代,分配规则不固定,取决于当前使用的垃圾收集器组合以及相关的参数配置。

以下列举几条最普遍的内存分配规则,供大家学习。

对象优先在 Eden 分配

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

??Minor GC vs Major GC/Full GC:

  • Minor GC:回收新生代(包括 Eden 和 Survivor 区域),因为 Java 对象大多都具备朝生夕灭的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。
  • Major GC / Full GC: 回收老年代,出现了 Major GC,经常会伴随至少一次的 Minor GC,但这并非绝对。Major GC 的速度一般会比 Minor GC 慢 10 倍 以上。

在 JVM 规范中,Major GC 和 Full GC 都没有一个正式的定义,所以有人也简单地认为 Major GC 清理老年代,而 Full GC 清理整个内存堆。

大对象直接进入老年代

大对象是指需要大量连续内存空间的 Java 对象,如很长的字符串或数据。

一个大对象能够存入 Eden 区的概率比较小,发生分配担保的概率比较大,而分配担保需要涉及大量的复制,就会造成效率低下。

虚拟机提供了一个 -XX:PretenureSizeThreshold 参数,令大于这个设置值的对象直接在老年代分配,这样做的目的是避免在 Eden 区及两个 Survivor 区之间发生大量的内存复制。(还记得吗,新生代采用复制算法回收垃圾)

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

JVM 给每个对象定义了一个对象年龄计数器。当新生代发生一次 Minor GC 后,存活下来的对象年龄 +1,当年龄超过一定值时,就将超过该值的所有对象转移到老年代中去。

使用 -XXMaxTenuringThreshold 设置新生代的最大年龄,只要超过该参数的新生代对象都会被转移到老年代中去。

动态对象年龄判定

如果当前新生代的 Survivor 中,相同年龄所有对象大小的总和大于 Survivor 空间的一半,年龄 >= 该年龄的对象就可以直接进入老年代,无须等到 MaxTenuringThreshold 中要求的年龄。

空间分配担保

JDK 6 Update 24 之前的规则是这样的:
在发生 Minor GC 之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间, 如果这个条件成立,Minor GC 可以确保是安全的; 如果不成立,则虚拟机会查看 HandlePromotionFailure 值是否设置为允许担保失败, 如果是,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小, 如果大于,将尝试进行一次 Minor GC,尽管这次 Minor GC 是有风险的; 如果小于,或者 HandlePromotionFailure 设置不允许冒险,那此时也要改为进行一次 Full GC。

JDK 6 Update 24 之后的规则变为:
只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小,就会进行 Minor GC,否则将进行 Full GC。

通过清除老年代中废弃数据来扩大老年代空闲空间,以便给新生代作担保。

这个过程就是分配担保。


??总结一下有哪些情况可能会触发 JVM 进行 Full GC。

  1. System.gc() 方法的调用
    此方法的调用是建议 JVM 进行 Full GC,注意这只是建议而非一定,但在很多情况下它会触发 Full GC,从而增加 Full GC 的频率。通常情况下我们只需要让虚拟机自己去管理内存即可,我们可以通过 -XX:+ DisableExplicitGC 来禁止调用 System.gc()。

  2. 老年代空间不足
    老年代空间不足会触发 Full GC操作,若进行该操作后空间依然不足,则会抛出如下错误:
    java.lang.OutOfMemoryError: Java heap space

  3. 永久代空间不足
    JVM 规范中运行时数据区域中的方法区,在 HotSpot 虚拟机中也称为永久代(Permanet Generation),存放一些类信息、常量、静态变量等数据,当系统要加载的类、反射的类和调用的方法较多时,永久代可能会被占满,会触发 Full GC。如果经过 Full GC 仍然回收不了,那么 JVM 会抛出如下错误信息:
    java.lang.OutOfMemoryError: PermGen space

  4. CMS GC 时出现 promotion failed 和 concurrent mode failure
    promotion failed,就是上文所说的担保失败,而 concurrent mode failure 是在执行 CMS GC 的过程中同时有对象要放入老年代,而此时老年代空间不足造成的。

  5. 统计得到的Minor GC晋升到旧生代的平均大小大于老年代的剩余空间

 

jvm-内存分配与回收策略

  JAVA技术体系中的自动内存管理实际上就是自动化的解决了给对象分配内存以及回收给对象分配的内存这两个问题。回收部分通过之前的《GC设计思路分析》和《垃圾收集器》这两篇博文进行了总结,那么接下来主要就是... 查看详情

jvm-内存分配与回收策略

  JAVA技术体系中的自动内存管理实际上就是自动化的解决了给对象分配内存以及回收给对象分配的内存这两个问题。回收部分通过之前的《GC设计思路分析》和《垃圾收集器》这两篇博文进行了总结,那么接下来主要就是谈... 查看详情

jvm内存分配与回收策略

...致是Eden、FromSurvivor和ToSurvivor。划分的目的是更好地回收内存或更快地分配内存。根据JVM规范,Java堆可以处于物理上不连续的内存空间中,要求逻辑上连续。   1对象优先在Eden区中分配  大多数情况下,对象在新生代Eden... 查看详情

内存分配与回收策略

内存分配与回收策略  Java技术体系中的自动内存管理最终可以归结为自动化地解决两个问题:给对象分配内存和回收分配给对象的内存。关于内存回收这一点,我们在Java垃圾收集机制中详细介绍了各种回收算法以及JVM中常见... 查看详情

jvm内存分配与回收策略

...致是Eden、FromSurvivor和ToSurvivor。划分的目的是更好地回收内存或更快地分配内存。根据JVM规范,Java堆可以处于物理上不连续的内存空间中,要求逻辑上连续。  1对象优先在Eden区中分配  大多数情况下,对象在新生代Eden区中... 查看详情

jvm系列三:内存分配与回收策略

内存分配策略1、对象优先分配在新生代Eden区多数情况下,对象分配在新生代的Eden,若Eden区域内存不够,则引发一次MinorGC 2、大对象直接进入老年代大对象直接分配在老年代,避免新生代里出现从Eden到Survivor频繁的内存复制... 查看详情

jvm之内存分配与回收策略

前言   对象的内存分配,往大的方向上讲,就是在堆上分配,少数情况下也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节决定于当前使用的是哪种垃圾收集器组合,当然还有虚拟机中与内存... 查看详情

jvm内存分配与回收策略

对象优先在Eden分配大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次MinorGC。MinorGC:新生代GC,指发生在新生代的垃圾收集动作,因为Java对象大多具备朝生夕灭的特性,所以MinorGC非... 查看详情

jvm-内存分配与回收策略

...虑的问题。  通过之前对JVM中的内存模型的分析以及GC的学习,我们知道JAVA内存分配往大了说就是在JAVA堆上分配内存,对象主要分配在新生代的Eden区;Sun Hotspot JVM为了提升对象内存分配的效率,对于所创建的... 查看详情

jvm系列jvm垃圾收集器与内存分配策略

众所周知,在java语言中,内存分配和回收是由jvm自动管理的。因此内存的分配和回收也是jvm三大功能之一。垃圾收集器(GC)需要完成三件事情:哪些内存需要回收?什么时候进行回收?如何回收?本篇博客将解答jvm是如何处理... 查看详情

jvm--垃圾回收

...,在对JVM有一定了解的基础上,接下来进行JVM垃圾收集的学习垃圾收集器与内存分配策略1.概述  内存的动态分配与内存回收技术已经很成熟了,了解GC和内存分配:一方面为了当出现内存溢出,内存泄漏的时候排查问题,另... 查看详情

jvm学习-java垃圾回收-内存分配

...要说到了垃圾回收算法、垃圾收集器等,这篇我们来学习下对象在内存分配的策略;一、概述对象在内存分配,一般都是在堆内存上分配,主要是会分配到新生代的Eden区,如果有开启本地线程分配缓冲区,... 查看详情

jvm之gc日志分析与对象内存分配回收策略(代码片段)

GC日志分析与内存分配回收策略一.GC日志分析的引入二.GC的分类与GC日志结构剖析三.JDK1.9以前的日志分析四.JDK1.9以后的日志分析五.对象内存分配回收策略一.GC日志分析的引入🐬GC日志分析的重要性:阅读分析虚拟机和垃... 查看详情

jvm,深入理解java虚拟机,内存分配与回收策略(代码片段)

Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象的内存。关于回收内存这一点,我们已经使用了大量篇幅去介绍虚拟机中的垃圾收集器体系以及运作原... 查看详情

jvm内存分配与回收

1.内存分配与回收策略内存自动管理:自动化的解决了对象内存分配和回收对象内存的问题。一般在堆上分配对象,也可能经过JTI编译后间接在栈上分配。主要分配在新生代的Eden区,如果启动了本地线程分配缓冲(线程缓冲区TLA... 查看详情

java虚拟机序列java中的垃圾回收与内存分配策略

...】java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略。垃圾回收(GarbageCollection,GC)是java语言的一大特色,在J... 查看详情

jvm-垃圾收集器与内存分配策略

判断对象是否存活引用计数法:强引用->软引用(内存溢出异常前第二次回收)->弱引用->虚引用可达性分析算法:一个对象到GCRoots没有任何引用链(ReferenceChain),则证明此对象不可用无用的类标准该类所有的实例都已回收... 查看详情

《深入理解jvm——gc算法与内存分配策略》

 JVM深入理解JVM(2)——GC算法与内存分配策略 PostedbyCrowonAugust10,2017说起垃圾收集(GarbageCollection,GC),想必大家都不陌生,它是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行... 查看详情