Java虚拟机根据对象存活的周期不同,把堆内存划分为几块,一般分为新生代、老年代和永久代(对HotSpot虚拟机而言),这就是JVM的内存分代策略。

为什么要分代?

堆内存是虚拟机管理的内存中最大的一块,也是垃圾回收最频繁的一块区域,我们程序所有的对象实例都存放在堆内存中。给堆内存分代是为了提高对象内存分配和垃圾回收的效率。试想一下,如果堆内存没有区域划分,所有的新创建的对象和生命周期很长的对象放在一起,随着程序的执行,堆内存需要频繁进行垃圾收集,而每次回收都要遍历所有的对象,遍历这些对象所花费的时间代价是巨大的,会严重影响我们的GC效率,这简直太可怕了。

有了内存分代,情况就不同了,新创建的对象会在新生代中分配内存,经过多次回收仍然存活下来的对象存放在老年代中,静态属性、类信息等存放在永久代中,新生代中的对象存活时间短,只需要在新生代区域中频繁进行GC,老年代中对象生命周期长,内存回收的频率相对较低,不需要频繁进行回收,永久代中回收效果太差,一般不进行垃圾回收,还可以根据不同年代的特点采用合适的垃圾收集算法。分代收集大大提升了收集效率,这些都是内存分代带来的好处。

内存分代划分

      Java虚拟机将堆内存划分为新生代老年代永久代,永久代是HotSpot虚拟机特有的概念,它采用永久代的方式来实现方法区,其他的虚拟机实现没有这一概念,而且HotSpot也有取消永久代的趋势,在JDK 1.7中HotSpot已经开始了“去永久化”,把原本放在永久代的字符串常量池移出。永久代主要存放常量、类信息、静态变量等数据,与垃圾回收关系不大,新生代和老年代是垃圾回收的主要区域。内存分代示意图如下:

 新生代(Young)

新生成的对象优先存放在新生代中,新生代对象朝生夕死,存活率很低,在新生代中,常规应用进行一次垃圾收集一般可以回收70% ~ 95% 的空间,回收效率很高。

HotSpot将新生代划分为三块,一块较大的Eden空间和两块较小的Survivor空间,默认比例为8:1:1。划分的目的是因为HotSpot采用复制算法来回收新生代,设置这个比例是为了充分利用内存空间,减少浪费。新生成的对象在Eden区分配(大对象除外,大对象直接进入老年代),当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC。

GC开始时,对象只会存在于Eden区和From Survivor区,To Survivor区是空的(作为保留区域)。GC进行时,Eden区中所有存活的对象都会被复制到To Survivor区,而在From Survivor区中,仍存活的对象会根据它们的年龄值决定去向,年龄值达到年龄阀值(默认为15,新生代中的对象每熬过一轮垃圾回收,年龄值就加1,GC分代年龄存储在对象的header中)的对象会被移到老年代中,没有达到阀值的对象会被复制到To Survivor区。接着清空Eden区和From Survivor区,新生代中存活的对象都在To Survivor区。接着, From Survivor区和To Survivor区会交换它们的角色,也就是新的To Survivor区就是上次GC清空的From Survivor区,新的From Survivor区就是上次GC的To Survivor区,总之,不管怎样都会保证To Survivor区在一轮GC后是空的。GC时当To Survivor区没有足够的空间存放上一次新生代收集下来的存活对象时,需要依赖老年代进行分配担保,将这些对象存放在老年代中。

老年代(Old)

       在新生代中经历了多次(具体看虚拟机配置的阀值)GC后仍然存活下来的对象会进入老年代中。老年代中的对象生命周期较长,存活率比较高,在老年代中进行GC的频率相对而言较低,而且回收的速度也比较慢。

永久代(Permanent)

       永久代存储类信息、常量、静态变量、即时编译器编译后的代码等数据,对这一区域而言,Java虚拟机规范指出可以不进行垃圾收集,一般而言不会进行垃圾回收。

Minor GC 和 Full GC的区别

       新生代GC(Minor GC):Minor GC指发生在新生代的GC,因为新生代的Java对象大多都是朝生夕死,所以Minor GC非常频繁,一般回收速度也比较快。当Eden空间不足以为对象分配内存时,会触发Minor GC。

老年代GC(Full GC/Major GC):Full GC指发生在老年代的GC,出现了Full GC一般会伴随着至少一次的Minor GC(老年代的对象大部分是Minor GC过程中从新生代进入老年代),比如:分配担保失败。Full GC的速度一般会比Minor GC慢10倍以上。当老年代内存不足或者显式调用System.gc()方法建议JVM回收时,若JVM真的回收会触发Full GC。

转载于https://www.cnblogs.com/fangfuhai/p/7206944.html

转载:JVM内存分代策略的更多相关文章

  1. Java虚拟机:JVM内存分代策略

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! Java虚拟机根据对象存活的周期不同,把堆内存划分为几块,一般分为新生代.老年代和永久代(对HotSpot虚拟机而言),这就是JVM的内存 ...

  2. JVM内存区域以及各区域的内存溢出异常,内存分代策略,垃圾收集算法,各种垃圾收集器

    本文整理自周志明老师的<深入理解Java虚拟机-JVM高级特性与最佳实践>第3版的第二章和第三章. 加上了一些网上拼拼凑凑的图片,个人认为很多博客复制来复制去,最后的东西都看不懂,所以从书 ...

  3. JVM的分代思想

    Java虚拟机根据对象存活的周期不同,把堆内存划分为几块,一般分为新生代.老年代和永久代(对HotSpot虚拟机而言),这就是JVM的内存分代策略. 永久代是HotSpot虚拟机特有的概念,它采用永久 ...

  4. JVM系列-分代收集垃圾回收

    Java自动垃圾回收(Automatic Garbage Collection)是自动回收堆上不再使用的内存,new的对象在程序中没有引用指向它,就会被回收.回收的实现很多,有Reference Co ...

  5. 轻松理解JVM的分代模型

    前言 上篇文章我们一起对jvm的内存模型有了比较清晰的认识,小伙伴们可以参考JVM内存模型不再是秘密这篇文章做一个复习. 本篇文章我们将针对jvm堆内存的分代模型做一个详细的解析,和大家一起轻松理解j ...

  6. java jvm内存管理/gc策略/参数设置

    1. JVM内存管理:深入垃圾收集器与内存分配策略 http://www.iteye.com/topic/802638 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想 ...

  7. 浅谈Java堆内存分代回收

    目录 1.概述 2.堆内存是如何分代的 3.各分代之间是如何配合工作的 1.概述 与C++不同的是, 在Java中我们无需关心对象占用空间的释放, 这主要得益于Java中的垃圾处理器(简称GC)帮助我 ...

  8. [转载] JVM 内存结构

    转载自:http://gityuan.com/2015/10/17/java-memory/

  9. JVM的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集

    (转自:http://my.oschina.net/u/436879/blog/85478) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认 ...

随机推荐

  1. FastJSON实现详解

    摘要:“快”作为程序员追逐的终极目标之一,而FastJSON则很好的证明了这一特性.本期<问底>,静行将带大家见证它序列化和反序列化的实现过程,一起领略它的“快”感. 还记得电影<功 ...

  2. PAT甲级——A1110 Complete Binary Tree【25】

    Given a tree, you are supposed to tell if it is a complete binary tree. Input Specification: Each in ...

  3. Java之RabbitMQ(一)与SpringBoot整合

    应用场景:异步处理.应用解耦.流量削峰 参照:https://blog.csdn.net/weixin_38364973/article/details/82834348 开端 RabbitAutoC ...

  4. uoj#370【UR #17】滑稽树上滑稽果

    题目 低智选手果然刷不动uoj 首先考虑一下构造一棵树显然是骗你玩的,按位与这个东西越做越小,挂到链的最下面显然不会劣于挂到之前的某一个点下面,所以我们只需要求一个排列使得答案最小就好了 设\(A=\ ...

  5. 【bzoj 2870】 最长道路tree

    题目 边分治 边分和点分相比就是找到一条重心边,考虑所有经过这条边的路径,之后断开这条边分成两个联通块,继续分治 由于每次分治重心是一条边,所以只会产生两个联通块,考虑两个联通块显然要比像点分那样考虑 ...

  6. C 遍历目录及其子目录

    遍历某一目录,获取该目录下所有文件路径的数组 #include <iostream> #include <dirent.h> #include <vector> v ...

  7. swagger请求参数在header中添加token

    网友大部分说的是如下配置 参照配置然而没有作用 注掉改红框内的配置,在方法上加如下注释就可以用 @ApiImplicitParams({ @ApiImplicitParam(paramType = & ...

  8. 2019-7-1-Roslyn-让编译时候-Message-内容默认输出

    title author date CreateTime categories Roslyn 让编译时候 Message 内容默认输出 lindexi 2019-07-01 14:16:59 +080 ...

  9. Nand Flash 控制器中的硬件 ECC 介绍

    ECC 产生方法 ECC 是用于对存储器之间传送数据正确进行校验的一种算法,分硬件 ECC 和软件 ECC 算法两种,在 S3C2410 的 Nand Flash 控制器中实现了由硬件电路(ECC 生 ...

  10. WPF 先显示登录成功,验证成功后显示主窗口

    /// 设置显示登录窗口的方法: /// 在 App.xaml 中把这句 /// 删掉 StartupUri="MainWindow.xaml" 改为 StartupUri=&qu ...