Java垃圾回收(二) 堆内存的分代回收

堆内存的分代回收

Java针对堆的垃圾回收,将堆分为了三个较小的部分:新生代、老年代、持久代。新生代主要使用复制和标记-清除垃圾回收算法,年老代主要使用标记-整理垃圾回收算法,因此java虚拟中针对新生代和年老代分别提供了多种不同的垃圾收集器。

1. 分代回收的依据:

  • 对象生存时间长短:大部分对象在Young期间就被回收。
  • 不同代采用不同的垃圾回收策略:对存活时间不同的对象分类,用不同的垃圾回收算法进行高效的有针对回收。

2. 堆内存的分代:

  • Young代

  • 回收机制:因为对象数量少,所以采用复制(stop-and-copy)回收。
  • 组成区域:由1个Eden区和2个Survivor区构成,同一时间的两个Survivor区,一个用来保存对象,另外一个是空的;绝大部分新生成的对象都放在Eden区,当Eden区将满,JVM会因申请不到内存,而触发Young GC ,进行Young代垃圾回收,就把Survivor的from区中可达对象复制到To区中,再清除Eden、From区,From区和To区互换,以便执行下一次的垃圾回收。一些生存时间长的对象直接分配到Old代中(关于生存时间长短,每次Young GC都会使Survivor区存活对象值+1,直到阈值)。
  • 对象来源:绝大多数对象先分配到Eden区,一些大的对象会直接被分配到Old代中。
  • 回收频率:因为Young代中大部分对象很快的进入不可达状态,因此回收频率高且回收速度快。
  • Old 代:
  • 回收机制:采用标记压缩算法回收。(Concurrent-Mark–Sweep)
  • 对象来源:较大型的对象会直接进入Old代,另外再Young中生存的时间很长的可达对象也会进入Old代。
  • 回收频率:因为很少对象会死掉,所以频率不高,而且每次回收的时间很长,因为存在较多的大的对象。发生一次 Major GC 至少伴随一次Young GC,一般比Young GC慢十倍以上。
  • Permanent代:
  • 用途:用来装载Class,方法等信息,默认为64M,不会被回收。
  • 对象来源:eg:动态生成类的时候,会不停的动态加载class文件,但是这些占用的内存不会被回收,不停的加载会让Permanent代的内存耗尽,会出现OOM的现象。
  • 回收频率:不会被回收。
时间: 2024-09-30 19:43:47

Java垃圾回收(二) 堆内存的分代回收的相关文章

垃圾回收算法(5)分代回收

分代垃圾回收,基于的是“大部分的对象,在生成后马上就会变成垃圾”这一经验上的事实为设计出发点.此前讨论过基于引事实的另一个垃圾回收算法,引用计数出的一些优化思路. 分代的关键是: 给对象记录下一个age,随着每一次垃圾回收,这个age会增加: 给不同age的对象分配不同的堆内内存空间,称为某一代: 对某一代的空间,有适合其的垃圾回收算法: 对每代进行不同垃圾回收,一般会需要一个额外的信息:即每代中对象被其他代中对象引用的信息.这个引用信息对于当前代来说,扮演与"root"一样的角色,也

JVM堆内存控制/分代垃圾回收

JVM的堆的内存, 是通过下面面两个参数控制的 -Xms 最小堆的大小, 也就是当你的虚拟机启动后, 就会分配这么大的堆内存给你 -Xmx 是最大堆的大小 当最小堆占满后,会尝试进行GC,如果GC之后还不能得到足够的内存(GC未必会收集到所有当前可用内存),分配新的对象,那么就会扩展堆,如果-Xmx设置的太小,扩展堆就会失败,导致OutOfMemoryError错误提示. 实际上,细节不止于此, 堆还会被分成几个不同的区域,分别应用不同的GC算法 http://unixboy.javaeye.c

JVM堆内存的分代

虚拟机的堆内存共划分为三个代:年轻代(Young Generation).年老代(Old Generation)和持久代(PermanentGeneration).其中持久代主要存放的是Java类的类信息,与垃圾收集器要收集的Java对象关系不大.所以,年轻代和年老代的划分才是对垃圾收集影响比较大的. 年轻代 所有新生成的对象首先都是放在年轻代的.年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象.年轻代分三个区.一个Eden区,两个Survivor区(一般而言).大部分对象在Eden区中生

java虚拟机学习-JVM调优总结-分代垃圾回收详述(9)

为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如Http请求中的Session对象.线程.Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长.但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,比如:String对象,由于其不变类的特性,系统会产生大量的这些对象,有些对象甚至

是堆内存分为年轻代和年老代!!!

1.是堆内存分为年轻代和年老代!!! 2.是堆内存分为年轻代和年老代!!! 3.是堆内存分为年轻代和年老代!!! 4. 1) 在Young Generation中,有一个叫Eden Space的空间,主要是用来存放新生的对象,还有两个Survivor Spaces(from.to),它们的大小总是一样,它们用来存放每次垃圾回收后存活下来的对象. 2) 在Old Generation中,主要存放应用程序中生命周期长的内存对象. 3) 在Young Generation块中,垃圾回收一般用Copyi

浅谈Java堆内存分代回收

概述 与C++不同的是:在Java中我们无需关心对象占用空间的释放,这主要得益于Java中的垃圾处理器(简称GC)帮助我们自动的进行对象占用空间的释放. 下面我们带着几个问题来学习: 堆内存是如何分代的? 各分代之间是如何配合工作的? 1.堆内存是如何分代的? 用一张图片来描述(面积大小不代表实际占用空间大小) 堆内存分为:年轻代(Young) + 老年代(Old),年轻代又分为:Eden区 + Survivor区 * 2. 通常年轻代中的各区比值为:Eden区:Survivor0 :Survi

JAVA面试题:堆内存和栈内存

java把内存划分为两种:一种是栈(stack)内存,一种是堆(heap)内存 在函数中定义的一些基本类型的变量和对象的引用变量都在栈内存中分配,当在一段代码块定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用 堆内存用来存放由new创建的对象和数组,在堆中分配的内存,由jvm(java virtual machine)的自动垃圾回收器来管理,在堆中产生了一个数组或对象后,还可以在栈中定义一个特

java多线程解读二(内存篇)

线程的内存结构图 一.主内存与工作内存 1.Java内存模型的主要目标是定义程序中各个变量的访问规则.此处的变量与Java编程时所说的变量不一样,指包括了实例字段.静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,因为它们是线程私有的,不会被共享. 2.Java内存模型中规定了所有的变量都存储在主内存中,每条线程还有自己的虚拟内存.线程的虚拟内存中保存了该线程使用到的变量到主内存副本拷贝.线程对变量的所有操作(读取.赋值)都必须在自己的虚拟内存中进行,而不能直接读写主内存中的变量.不同

java垃圾回收和堆内存布局

java虚拟机是通过垃圾回收的方式进行内存回收的,C/C++可以通过代码控制内存释放,防止内存泄露,设置不同的垃圾回收方式和参数都会影响垃圾回收的效果,而这对系统的稳定性及单机的支撑能力方面. jvm指令集里面没有提供垃圾回收的释放操作,所以不能直接释放内存,而要专门的垃圾回收器来完成垃圾回收的工作. 不同的垃圾回收器产品有不同的回收策略,先来看Oracle Hotspot JVM中内存的对布局,如图3.2 从上图可以看出,有三大区域Young/Tenured/Perm,也就是我们经常说的新生代