JAVA垃圾收集以及分配策略

一:基本概念
1:垃圾收集(Garbage Collection)GC:堆和方法区
(需要进行二次标记:1.对象不可达 2 是否有必要执行finalize()方法)
image

1.1 确定对象已死(不可能再被任何途径使用的对象)

  • 引用计数算法(java未使用这个算法):在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的
  • 可达性分析算法:是通过一系列“GC Roots”称为根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”,如果某个对象到“GC Roots”间没有任何引用链相连,或者用图论的话来说就是从GC Root到这个对象不可达时,则证明此对象是不可能再被使用的。
    GC Roots对象包括以下

    1. 虚拟机栈(栈帧中的本地变量表)中引用的对象(方法堆栈中使用到的参数、局部变量、临时变量),本地方法栈中JNI(即通常所说的Native方法)引用的对象。
    2. 静态属性引用的对象,常量引用的对象
    3. Java虚拟机内部的引用(基本数据类型对应的Class对象,一些常驻的异常对象(比如NullPointExcepiton、OutOfMemoryError)等,还有系统类加载器。)
    4. 所有被同步锁(synchronized关键字)持有的对象
    5. 反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等

    ps:还有一些局部回收或者分代收集对象。

1.2 引用(1.2之后)

    1. 强引用
        (类似“Object obj=new Object()”这种引用关系,若存在则不回收)
    2. 软引用(SoftReference类修饰)
         在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。
    3. 弱引用(WeakReference)
        只能生存到下一次垃圾收集发生为止。当垃圾收集器开始工作,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
    4. 虚引用(PhantomReference)

2:方法区的垃圾回收:废弃的常量或者不在使用的类型

   永久代类回收判断:-Xnoclassgc 设置
    1. 类所有的实例都已经被回收
    2. 加载该类的类加载器已经被回收
    3. 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
    查看类加载和卸载信-verbose:class以及-XX:+TraceClass-Loading、-XX:

+TraceClassUnLoading

3:垃圾回收算法

    3.1 标记-清除算法:缺点:效率问题,空间浪费问题(碎片)
    3.2 复制算法:将内存分为两块,每次只使用其中一块,内存用完。则将存活的copy到另一半内存上。(新生代回收使用这个算法)

image

    3.3 标记-整理算法(老年代使用):将存活对象向一端移动,然后回收边界以外内存
    

4:垃圾收集器

    4.1 CMS(开始标记,并发标记,重洗标记,并发清除)
    4.2 G1(将内存分块,存到优先列表。优先回收垃圾最多的区域)
    

5:对象分配

    首先分配在eden区(无空间,则发起mirror gc)-》大对象直接到老年代-》长期存活对象进入老年代(对象年龄计数器(15))-》survivor空间相同年龄对像占用内存>survivor空间一半直接进入老年代
      

你可能感兴趣的:(java)