zoukankan      html  css  js  c++  java
  • (转)GC ROOTS

    还是英文的技术博客更给力,更清楚,本人懒,没有翻译。 

    In your specific example, in any managed environment, Person is not a GC root; the GC root is the thingwhich holds the reference to Person. The difference is subtle, but important in the context of this question. Although my answer is specific to Java it is in general correct for any managed language. Your last paragraph is actually correct, but conflicts with the example given.

    The GC (Garbage Collector) roots are objects special for garbage collector. The Garbage Collector collects those objects that are not GC roots and are not accessible by references from GC roots.

    There are several kinds of GC roots. One object can belong to more than one kind of root. The root kinds are:

    • Class - class loaded by system class loader. Such classes can never be unloaded. They can hold objects via static fields. Please note that classes loaded by custom class loaders are not roots, unless corresponding instances of java.lang.Class happen to be roots of other kind(s).
    • Thread - live thread
    • Stack Local - local variable or parameter of Java method
    • JNI Local - local variable or parameter of JNI method
    • JNI Global - global JNI reference
    • Monitor Used - objects used as a monitor for synchronization
    • Held by JVM - objects held from garbage collection by JVM for its purposes. Actually the list of such objects depends on JVM implementation. Possible known cases are: the system class loader, a few important exception classes which the JVM knows about, a few pre-allocated objects for exception handling, and custom class loaders when they are in the process of loading classes. Unfortunately, JVM provides absolutely no additional detail for such objects. Thus it is up to the analyst to decide to which case a certain "Held by JVM" belongs.
     

    If you think of the objects in memory as a tree, the "roots" would be the root nodes - every object immediately accessible by your program.

    Person p = new Person();
    p.car = new Car(RED);
    p.car.engine = new Engine();
    p.car.horn = new AnnoyingHorn();

    There are four objects; a person, a red car, its engine and horn. Draw the reference graph:

         Person [p]
            |
         Car (red)
       /           
    Engine    AnnoyingHorn

    And you'll end up with Person at the "root" of the tree. It's live because it's referenced by a local variable, p, which the program might use at any time to refer to the Person object. This also goes for the other objects, through p.carp.car.engine, etc.

    Since Person and all other objects recursively connected to it are live, there would be trouble if the GC collected them.

    Consider, however, if the following is run after a while:

    p.car = new Car(BLUE);

    And redraw the graph:

         Person [p]
            |
         Car (blue)       Car (red)
                        /           
                    Engine    AnnoyingHorn

    Now the Person is accessible through p and the blue car through p.car, but there is no way the red car or its parts can ever be accessed again - they are not connected to a live root. They can be safely collected.

    So it's really a matter of taking every starting point (every local variable, globals, statics, everything in other threads and stack frames) — every root — and recursively following all the references to make up a list of all the "live" objects: objects which are in use and unsuitable for deletion. Everything else is garbage, waiting to be collected.

  • 相关阅读:
    26_为什么我的删除刷新没有办法删除动态添加的数据呢?
    075_not in (null):这代表是什么意思呢?
    074_form表单中的value值
    025_回调函数没有遍历出数据
    073_模糊查询
    072_jsp追加与刷新数据
    071_为什么要catch return.setCode()?
    070_jstl中的三目表达式
    069_都是查询语句时得事物?
    打印周报模板
  • 原文地址:https://www.cnblogs.com/sunshisonghit/p/4561252.html
Copyright © 2011-2022 走看看