`
chenzehe
  • 浏览: 532331 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java垃圾回收:GC在什么时候对什么做了什么

    博客分类:
  • JVM
 
阅读更多

        GC在什么时候对什么做了什么?

        要回答这个问题,先了解下GC的发展史、jvm运行时数据区的划分、jvm内存分配策略、jvm垃圾收集算法等知识。

        先说下jvm运行时数据的划分,粗暴的分可以分为堆区(Heap)和栈区(Stack),但jvm的分法实际上比这复杂得多,大概分为下面几块:

        1、程序计数器(Program Conuter Register)

        程序计数器是一块较小的内存空间,它是当前线程执行字节码的行号指示器,字节码解释工作器就是通过改变这个计数器的值来选取下一条需要执行的指令。它是线程私有的内存,也是唯一一个没有OOM异常的区域。

        2、Java虚拟机栈区(Java Virtual Machine Stacks)

        也就是通常所说的栈区,它描述的是Java方法执行的内存模型,每个方法被执行的时候都创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等。每个方法被调用到完成,相当于一个栈帧在虚拟机栈中从入栈到出栈的过程。此区域也是线程私有的内存,可能抛出两种异常:如果线程请求的栈深度大于虚拟机允许的深度将抛出StackOverflowError;如果虚拟机栈可以动态的扩展,扩展到无法动态的申请到足够的内存时会抛出OOM异常。

        3、本地方法栈(Native Method Stacks)

        本地方法栈与虚拟机栈发挥的作用非常相似,区别就是虚拟机栈为虚拟机执行Java方法,本地方法栈则是为虚拟机使用到的Native方法服务。

        4、堆区(Heap)

        所有对象实例和数组都在堆区上分配,堆区是GC主要管理的区域。堆区还可以细分为新生代、老年代,新生代还分为一个Eden区和两个Survivor区。此块内存为所有线程共享区域,当堆中没有足够内存完成实例分配时会抛出OOM异常。

        5、方法区(Method Area)

       方法区也是所有线程共享区,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。GC在这个区域很少出现,这个区域内存回收的目标主要是对常量池的回收和类型的卸载,回收的内存比较少,所以也有称这个区域为永久代(Permanent Generation)的。当方法区无法满足内存分配时抛出OOM异常。

        6、运行时常量池(Runtime Constant Pool)

        运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。

 

        垃圾收集(Garbage Collection)并不是Java独有的,最早是出现在Lisp语言中,它做的事就是自动管理内存,也就是下面三个问题:

1、什么时候回收

2、哪些内存需要回收

3、如何回收

 

 1、什么时候回收?

         上面说到GC经常发生的区域是堆区,堆区还可以细分为新生代、老年代,新生代还分为一个Eden区和两个Survivor区。

        1.1 对象优先在Eden中分配,当Eden中没有足够空间时,虚拟机将发生一次Minor GC,因为Java大多数对象都是朝生夕灭,所以Minor GC非常频繁,而且速度也很快;

        1.2 Full GC,发生在老年代的GC,当老年代没有足够的空间时即发生Full GC,发生Full GC一般都会有一次Minor GC。大对象直接进入老年代,如很长的字符串数组,虚拟机提供一个-XX:PretenureSizeThreadhold参数,令大于这个参数值的对象直接在老年代中分配,避免在Eden区和两个Survivor区发生大量的内存拷贝;

        1.3 发生Minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则进行一次Full GC,如果小于,则查看HandlePromotionFailure设置是否允许担保失败,如果允许,那只会进行一次Minor GC,如果不允许,则改为进行一次Full GC。

 

 2、哪些内存需要回收

        jvm对不可用的对象进行回收,哪些对象是可用的,哪些是不可用的?Java并不是采用引用计数算法来判定对象是否可用,而是采用根搜索算法(GC Root Tracing),当一个对象到GC Roots没有任何引用相连接,用图论的来说就是从GC Roots到这个对象不可达,则证明此对象是不可用的,说明此对象可以被GC。对于这些不可达对象,也不是一下子就被GC,而是至少要经历两次标记过程:如果对象在进行根搜索算法后发现没有与GC Roots相连接的引用链,那它将会第一次标记并且进行一次筛选,筛选条件是此对象有没有必要执行finalize()方法,当对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机调用执行过一次,这两种情况都被视为没有必要执行finalize()方法,对于没有必要执行finalize()方法的将会被GC,对于有必要有必要执行的,对象在finalize()方法中可能会自救,也就是重新与引用链上的任何一个对象建立关联即可。

 

 3、如何回收

        选择不同的垃圾收集器,所使用的收集算法也不同。

在新生代中,每次垃圾收集都发现有大批对象死去,只有少量存活,则使用复制算法,新生代内存被分为一个较大的Eden区和两个较小的Survivor区,每次只使用Eden区和一个Survivor区,当回收时将Eden区和Survivor还存活着的对象一次性的拷贝到另一个Survivor区上,最后清理掉Eden区和刚才使用过的Survivor区,Eden和Survivor的默认比例是8:1,可以使用-XX:SurvivorRatio来设置该比例。

       而老年代中对象存活率高,没有额外的空间对它进行分配担保,必须使用“标记-清理”或“标记-整理”算法。

 

分享到:
评论

相关推荐

    第6节: GC垃圾回收-02

    第6节: GC垃圾回收-02第6节: GC垃圾回收-02第6节: GC垃圾回收-02第6节: GC垃圾回收-02第6节: GC垃圾回收-02第6节: GC垃圾回收-02第6节: GC垃圾回收-02第6节: GC垃圾回收-02第6节: GC垃圾回收-02第6节: GC...

    java垃圾回收(gc)机制详解

    java垃圾回收(gc)机制详解

    java 垃圾回收 机制详解

    经过半个世纪的发展,内存的动态分配与内存回收技术已经相当成熟,一切看起来都进入了“自动化”时代,那为什么我们还要去了解GC和内存分配呢?答案很简单:当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为...

    java jstat 查看哪个进程频繁GC垃圾回收

    java查看哪个进程频繁GC垃圾回收

    JAVA垃圾回收机制

    垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变。垃圾收集的目的在于清除不再...

    Java垃圾回收GC机制

    Java垃圾回收GC机制

    java垃圾回收(gc)机制详解.pdf

    哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无非就是那些不可能再被任何途径使用的对象。

    Java垃圾回收知识,垃圾回收资料

    重要性:垃圾回收是Java垃圾回收器的核心功能,对性能和内存管理至关重要。准确理解垃圾回收的原理和机制,以及能够优化和调优垃圾回收过程的能力,是一个Java开发者必备的基本技能。 面试中可能会问到的垃圾回收...

    Java垃圾回收GC.xmind

    Java垃圾回收GC.xmind

    Java_GC垃圾回收调优指南

    让你对java gc 的工作原理有更深的了解 谢谢下载

    java垃圾回收知识全集

    Java 垃圾回收(Garbage Collection,简称 GC)是现代编程语言中的重要特性,为开发人员提供了自动化内存管理的能力。它通过自动识别和回收不再使用的内存,减轻了程序员手动释放内存的负担,提高了应用程序的稳定性...

    Java垃圾回收机制详解

    Java垃圾回收机制详解!! GC详解!!

    成为JavaGC专家PartII-如何监控Java垃圾回收

    成为JavaGC专家PartII—如何监控Java垃圾回收机制Java开发Java经验技巧共12页.pdf.zip

    详细介绍Java垃圾回收机制

    垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变。垃圾收集的目的在于清除不再...

    java垃圾回收日志分析工具GCViewer

    java垃圾回收日志分析工具GCViewer,包内含有15年9月1日所能下载到的最新代码及代码打包的jar文件,双击即可执行。 本GCViewer是最新版本的,是JDK1.8编译并支持JDK1.8的GC 日志文件分析。 GCViewer是业内支持率很高...

    Java垃圾回收机制和内存分配

    你认真演示了一遍,你就能明白JAVA的垃圾回收机制。当然文档写的不一定全面,比如文档当中关于老年区少年区有一页写的不是很完整,我也没有添加太多进去,但是还是很有很全面很有参考意义的。

    白话说java gc垃圾回收.docx

    白话说java gc垃圾回收.docx

    java垃圾回收技术,面试会问

    值得一看的基础东西,java的垃圾回收机制,之前百度面试被问到

    JVM垃圾回收机制与GC性能调优

    为什么先说JVM堆? JVM的堆是Java对象的活动空间,程序中的类的对象从中分配空间,其存储着正在运行着的应用程序用到的所有对象。这些对象的建立方式就是那些new一类的操作,当对象无用后,是GC来负责这个无用的...

Global site tag (gtag.js) - Google Analytics