JVM垃圾回收机制(一)

  垃圾回收器

  垃圾回收器主要负责:

    1. 分配内存;

    2. 保证所有正在被引用的对象还存在在内存中; 

    3. 回收不再被程序所引用的对象所占内存;

  Hotspot VM提供的垃圾回收器是一个分代的垃圾回收器(Generational GC),它将内存划分为不同的阶段,即不同生命周期的对象被放置在不同的内存空间中。这样的设计是基于弱年代假设(Weak Generational Hypothesis):大多数对象会很快变得不可达,只有很少有老对象指向新对象的引用。这种方式可以减少垃圾回收的停顿时间以及大范围对象的回收成本。Hotspot VM将其堆空间划分为3个分代空间:

    1. 年轻代Young Generation

      a. Java应用在分配Java对象时,这些对象会被分配到年轻代堆空间中去;

      b. 这个空间大多是小对象并且会被频繁回收;

      c. 由于年轻代堆空间的垃圾回收会很频繁,因此其垃圾回收算法会更加重视回收效率;

    2. 年老代Old Generationn

      a. 年轻代堆空间的长期存活对象会转移到(也许是永久性转移)年老代堆空间;

      b. 这个堆空间通常比年轻代的堆空间大,并且其空间增长速度较缓;

      c. 由于大部分JVM堆空间都分配给了年老代,因此其垃圾回收算法需要更节省空间,此算法需要能够处理低垃圾密度的堆空间;

    3. 持久代Permanent Generation

      a. 存放VM和Java类的元数据(metadata),以及interned字符串和类的静态变量;

  其堆空间示意图如下:

  其年轻代又分为三个空间:

    1. Eden——绝大多数刚刚被创建的对象会存放在此;

    2. Survivor1——在Eden空间执行了第一次GC之后,存活的对象被移动到此;

    3. Survivor2;

  注意:当一个Survivor空间饱和,还在存活的对象会被移动到另一个Survivor空间。之后会清空已经饱和的那个Survivor空间,Survivor空间必须至少有一个为空。如果两个Survivor空间都有数据,或者两个空间都是空的,那一定标志着你的系统出现了某种错误。

  GC类型

  JDK7一共提供了5种GC类型:

    1. Serial GC;

    2. Parallel GC;

    3. Parallel Old GC (Parallel Compacting GC);

    4. Concurrent Mark & Sweep GC  (or “CMS”);

    5. Garbage First (G1) GC;

  其中,Serial GC不应该被用在服务器上。这种GC类型在单核CPU的桌面电脑时代就存在了。使用Serial GC会显著的降低应用的性能指标。

  

  垃圾回收方式

  当这三个分代的堆空间比较紧张或没有足够的空间来为新到的请求分配的时候,垃圾回收机制就会起作用。有两种的垃圾回收方式:次收集(Minor GC)和全收集(Full GC)。当年轻代堆空间满了的时候,会触发Minor GC将还存活的对象移到年老代堆空间。当年老代堆空间满了的时候,会触发一个覆盖全范围的对象堆的Full GC。

  次收集

    1. 当年轻代堆空间紧张时会被触发;

    2. 相对于全收集而言,收集间隔较短;

  全收集

    1. 当老年代或者持久代堆空间满了,会触发全收集操作;

    2. 可以使用System.gc()方法来显式的启动全收集;

    3. 全收集一般根据堆大小的不同,需要的时间不尽相同,但一般会比较长;

  全收集通常时间很长,并且是程序无法延迟执行或者无法达到吞吐量目标的主因。GC的目标是去减少程序运行过程中垃圾回收的频率。为了达到这个目的,可以从这两方面入手:

    1. 从系统方面考虑:

      a. 尽量采用大堆,但是不要大到需要系统从磁盘上“换”页。一般而言,可用的RAM(没有被系统进程占用的)的80%都应该分配给JVM。

      b. Java堆空间越大,垃圾回收器和java应用在吞吐量(throughput)和延迟执行(latency)方面的效果越好。

    2. 从应用方面考虑:

      a. 减少对象分配(object allocations)操作,或者采用对象保留(object retention)方式有助于减小存活的数据大小,这也可以反过来帮助垃圾回收做的更好。

  如果老年代的对象需要引用一个新生代的对象,会发生什么呢?

  为了解决这个问题,年老代中存在一个”card table“,他是一个512 byte大小的块。所有年老代的对象指向年轻代对象的引用都会被记录在这个表中。当对年轻代执行GC的时候,只需要查询card table来决定是否可以被收集,而不用查询整个老年代。这个card table由一个write barrier来管理。write barrier给GC带来了很大的性能提升,虽然由此可能带来一些开销,但GC的整体时间被显著的减少。

  

时间: 2024-12-14 21:09:05

JVM垃圾回收机制(一)的相关文章

浅析JVM垃圾回收机制

首先我们需要知道Java的内存分配与回收全部由JVM垃圾回收机制自动完成.每种JVM实现可能采用不同的方法实现垃圾回收机制.在收购SUN之前,Oracle使用的是JRockit JVM,收购之后使用HotSpot JVM.目前Oracle拥有两种JVM实现并且一段时间后两个JVM实现会合二为一.HotSpot JVM是目前Oracle SE平台标准核心组件的一部分.市面上探讨垃圾回收机制,默认都是基于HotSpot JVM的.Ok,我们切入正题,先来看下JVM的内存区域模型, 这张图非常直观的展

JVM内存管理和JVM垃圾回收机制

JVM内存管理和JVM垃圾回收机制(1) 这里向大家描述一下JVM学习笔记之JVM内存管理和JVM垃圾回收的概念,JVM内存结构由堆.栈.本地方法栈.方法区等部分组成,另外JVM分别对新生代和旧生代采用不同的垃圾回收机制. AD: 你对JVM内存组成结构和JVM垃圾回收机制是否熟悉,这里和大家简单分享一下,希望对你的学习有所帮助,首先来看一下JVM内存结构,它是由堆.栈.本地方法栈.方法区等部分组成,结构图如下所示. JVM学习笔记 JVM内存管理和JVM垃圾回收 JVM内存组成结构 JVM内存

java JVM垃圾回收机制

Java语言出来之前,大家都在拼命的写C或者C++的程序,而此时存在一个很大的矛盾,C++等语言创建对象要不断的去开辟空间,不用的时候有需要不断的去释放控件,既要写构造函数,又要写析构函数,很多时候都在重复的allocated,然后不停的~析构.于是,有人就提出,能不能写一段程序在实现这块功能,每次创建,释放控件的时候复用这段代码,而无需重复的书写呢? 1960年 基于MIT的Lisp首先提出了垃圾回收的概念,用于处理C语言等不停的析构操作,而这时Java还没有出世呢!所以实际上GC并不是Jav

JVM垃圾回收机制入门

前言 数据库是大家会普遍重视的一个领域,异步通信一般用不到,虚拟机在大部分时候不会出问题,常被人忽视,所以我打算先学习虚拟机,从零单排Java高性能问题. 堆内存存储结构 Java6是以年代来规划内存的,而Java7的G1收集器则相反,这里以Java6为准. Survivor1和Survivor2是一样大的,必有一个始终为空,容量小于Eden. 垃圾回收机制 年轻代采用复制算法,当回收时,将Eden和Survivor中还存活的对象一次性地复制到另外一块Survivor上,然后清理掉Eden和刚才

JVM垃圾回收机制总结(3) :按代垃圾收集器

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

JVM 垃圾回收机制( 一) 回收对象的判定

关于JVM 的垃圾回收机制,我们一般都没过多深入,因为JAVA 和 C++ 的一个很大区别就是,JAVA 帮我们做了垃圾回收,而不用像C++ 那么样手动进行回收,当然任何自动的东西都存在一定弊端,比如机器人,即使自动程度很高,但是在处理某些感情问题上,肯定处理上就会有遗漏,开个玩笑啦, 下面我们先来了解一下JVM 的垃圾回收是怎么回事. 一.如何判断对象已经死亡 JVM 会回收那些不在使用的对象,或者说是已经死亡的对象,从而达到节省空间的目的,那么我们肯定的判断哪些对象已经死了,不在使用呢? 1

JVM垃圾回收机制与算法

JVM内存由几个部分组成:堆.方法区.栈.程序计数器.本地方法栈 JVM垃圾回收仅针对公共内存区域,即:堆和方法区进行,因为只有这两个区域在运行时才能知道需要创建些对象,其内存分配和回收都是动态的. 一.垃圾回收策略 1.1分代管理 将堆和方法区按照对象不同年龄进行分代: (Young Generation and Old Generation)堆中会频繁创建对象,基于一种分代的思想,按照对象存活时间将堆划分为新生代和旧生代两部分,并不是一次垃圾回收新生代存活的对象就放入旧生代, 而是要经过几次

简单测试JVM垃圾回收机制 System.gc()方法

简单的写一个方法测试Java的垃圾回收机制 System.gc()可以提醒JVM虚拟机去进行垃圾回收了,但是不一定成功. /** * 覆写Object中的finalize()方法 */ public class LJ { @Override protected void finalize() throws Throwable { System.out.println("垃圾正在回收..........."); } } public class GCDemo { /** * @param

深入JVM垃圾回收机制,值得你收藏

JVM可以说是为了Java开发人员屏蔽了很多复杂性,让Java开发的变的更加简单,让开发人员更加关注业务而不必关心底层技术细节,这些复杂性包括内存管理,垃圾回收,跨平台等,今天我们主要看看JVM的垃圾回收机制是怎么运行的,希望能够帮到大家, 哪些对象是垃圾呢? Java程序运行过程中时刻都在产生很多对象,我们都知道这些对象实例是被存储在堆内存中,JVM的垃圾回收也主要是针对这部分内存,每个对象都有自己的生命周期,在这个对象不被使用时,这个对象将会变成垃圾对象被回收,内存被释放,那么如何判断这个对