zoukankan      html  css  js  c++  java
  • Java GC 概念摘要

      很长时间,我想Java的GC做一个小小的总结,他有没有时间。根据最近看了java paper向上java gc文章,我觉得好,读读。顺便说一下,总结下。

      java paper的GC文章地址,里面有非常多java技术文章。写的都不错。


    1、Java GC 简单介绍

    JVM的垃圾回收机制使开发人员不必过多考虑内存的申请与释放,这样减少了软件开发的成本和语言的学习成本。

    不同的JVM对GC的实现是不同的,眼下Oracle维护着两种JVM。JRockit JVM,HotSpot JVM。

    本文讨论的JVM是居于HotSpot的JVM。

    1、执行时数据区域

    方法区、Heap内存。Java Stack, PC Registers,本地方法栈

    (下面图片均来自网络)


    2、运行引擎

    JIT Compiler, Garbage Collector


    2、Heap Memory

    在执行时。java对象的实例均被分配在heap内存中。当对象不被引用的时候。会被垃圾回收器标记为eviction,然后回收。最后释放在heamp中所占用的空间。

    Java Heap Memory 分为三个区域:
    1、Young Generation

    1、Eden  不论什么实例进入执行时的内存区域都是从Eden进入的
    2、S0 存活久一点的实例就能够从Eden进入到S0
    3、S1 存活更久的实例从S0进入S1
    2、Old Generation

    tenured (终身制的),实例从S1晋升到终身制区域
    3、Permanet Generation

    包括元数据信息。如class,method的detail信息


    翻译一段来自java paper的Heap介绍:

    Eden Space:
    每当一个实例被创建。就会分配到eden空间。

    Survivor Space (S0 and S1):
    作为minor GC的一部分,对象假设还在被引用的,就会从移动到S0.

    在minor GC时,假设对象没有被引用了,该对象就会被标记为要驱赶出内存中的对象。

    Old Generation:

    老年代是heap memory的逻辑部分,当垃圾收集器进行minor GC的时候,S1中还在存活的对象实例将从S1 移动 到 Old, 在S1中失去引用的部分,将被标记为从内存中驱赶。

    Major GC:
    老年代中的对象在进行Major GC时,那些失去引用的对象将被标记为从内存中驱赶。



    Memory Fragmentation:
    内存片段:当实例从heap memory中删除时,被删除后内存位置能够供新分配的对象使用,内存碎片须要被整理成连续的空间,内存碎片整理。从而能进行高速的分配内存空间。


    在驱赶对象实例和恢复内存空间之前,要对对象实例调用finalize()方法来对 该对象实例持有的资源进行释放。
    虽然finalize()方法一定在恢复内存空间前运行。可是顺序是无序的。是没有规定时限的。对象多实例之间的释放顺序不能提前决定,它们甚至可能是并行的进行。



    3、GC 过程

    Young 和 Old 的关系是 晋升关系

    联想起来,事实上能够这样打个例如,就是学生上学的场景:

    Heap Memory中的GC就是上学的问题。

    我们把这几个区域比作学校。实例比作学生


    Young
    Eden    S0    S1     
    小学    初中  高中

    Old
    大学

    Permanet
    学生元信息库


    描写叙述GC的过程就非常通俗易懂啦。

    推断是否晋升,是否标记释放,能够用reference来推断。那么:

    still referenced  仍然被引用的 (就是仍然愿意学习学生)
    dereferenced  失去引用的(就是不愿意学习的学生)

    MinorGC:(发生在Young内)

    1、比方一个学生刚上学,那么他肯定首先分配到小学,即Eden。

    2、假设在小学里还想继续学习的学生,即still refernced的学生,就会晋升到初中S0进行学习。不想学习的学生。即dereferenced 会被标记为毕业,会被垃圾回收。

    3、假设在初中里还想继续学习的学生,即still refernced的学生,就会晋升到高中S1进行学习。即dereferenced 会被标记为毕业。会被垃圾回收。



    MajorGC:(发生在Old)

    当在高中毕业后S1。还想继续学习的,那么就会被晋升到大学Old。

    发生MajorGc时,Old中会回收失去引用的实例。还被引用的将不被回收,还在Old大学里继续学习。当大学里装的学生太多了,就会触发OutOfMemoryError了。

    (下面图片来自网络)


    4、对象的回收

    什么情况下对象会被回收?
     
    Strong Reference     Not eligible for garbage collection  - 强引用的对象实例不会被回收
    Soft Reference     Garbage collection possible but will be done as a last option - 软引用的对象实例可能会被回收。可是一定是在不得不回收的情况下才回收。
    Weak Reference     Eligible for Garbage Collection - 弱引用的肯定会被回收
    Phantom Reference     Eligible for Garbage Collection - 幽灵引用的肯定会被回收


    1、声明后从来都没使用的对象。编译器会自己主动给该对象置为null,会被编译器标记为eviction。
    编译器会将那么不会在兴许使用的对象。在执行时之前提前将其提前回收。

    2、典型的一个样例,一个实例的全部属性都存在register中,訪问实例的属性值是从register中读取的。假设这个实例在未来不会将属性值写回实例,那么该实例还是会被标记为驱赶。



    3、null值赋给实例。假设该实例没有其他实例的引用,则会被标记回收。

    4、当finalize方法被调用。JVM会释放在那个线程的全部同步锁。



    5、总结

      JVM是一套标准。有非常多种实现。我们最常接触的是HotSpot JVM,对于不同的JVM。垃圾回收器的实现也不同。

      JVM中主要是分为执行时数据区域 和 执行引擎。

      Heap Memory中被划分为Eden。S0,S1。Old,Perm

      GC的过程就是这Eden到S0,S0到S1,S1到Old的晋升过程,分为minorGC 和 MajorGC(FullGc)。

      强引用对象不会被垃圾回收,软引用普通情况下不会被回收,实在不能回收时最后才会被回收。

    弱引用和幽灵引用的都会被回收。


    ——EOF——

    原创文章,转载请注明来自:http://blog.csdn.net/oopsoom/article/details/40348125

  • 相关阅读:
    【转】关于html元素的disabled,readonly 的详细分析
    拦截过滤器、前端控制器和应用控制器
    【PHP设计模式】创建型之原型模式(Prototype)
    【PHP设计模式】创建型之抽象工厂(abstract factory)
    【PHP设计模式】值对象模式
    PHP基础知识系列:PHP5新特征
    JavaScript 设计模式系列:基础知识
    【PHP设计模式】结构型之享元模式(Flyweight)
    【PHP设计模式】行为型之职责链(Chain of Responsibleity)
    【PHP设计模式】结构型之代理(Proxy)
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/5029736.html
Copyright © 2011-2022 走看看