jvm_第三章:垃圾收集与内存分配策略

1:回收哪些内存:

程序计数器,虚拟机栈,本地方法栈属于线程私有,随线程而生,随线程而灭,所以主要考虑方法区和堆内存的回收:2

2:哪些对象可以被回收:

  引用计数算法:

  可达性分析算法:GCRoots包括:

  • 虚拟机栈中的引用的对象;
  • 方法区中静态属性引用的对象;
  • 方法区中常量引用的对象;
  • 本地方法栈中native方法引用的对象

3:引用的分类:

  • 强引用:例如 Object  object=new Object()这类为强引用,只要强引用还存在,GC不会主动回收这类
  • 软引用:还有用但非必须的对象,在系统将要发生内存溢出异常时,会把这些对象列入回收列表并进行二次垃圾回收,如果还不够内存,则报内存溢出错误-->SoftReference
  • 弱引用:下次回收时,无论当前内部才能是否足够,都会对这些弱引用对象进行回收   -->实现用WeakReference
  • 虚引用

4:对象自救:

对象不可达后,如果对象覆盖了finalize方法,则会被放进FQuene等待finalize的执行,对象可以在finalize总拯救自己,但虚拟机不保证finalize方法的执行(通过创建一个低级Finalizer线程,可以再finalize方法中弄崩内存回收系统),如果在finalize中重新拯救自己,会被移除“”即将回收“”的集合:比如将自己赋值给某个类的成员变量

注意:任何一个对象的finalize方法都只会被系统自动调用一次,如果对象面临下一次回收,将没有机会执行finalize();

5:方法区的回收;

对无用类的卸载:该类没有实例存在,该类的classLoader被回收了,该类对应的Class没有在任何一个地方被引用   

 

下面对垃圾回收算法总结

Eden和survivor采用复制算法:减少内存碎片产生和频繁的内存回收(针对标记-清除算法)当进行minor GC时,会把eden和一个Survivor存活的对象复制到另一个survivor里面,然后清除eden和原来的survivor,下次两个survivor替换身份继续进行,,,eden:survivor1:survivor2=8:1:1但是不保证每次回收只有不多于10%的内存,所以需要老年代进行内存担保,就是,对对象进行分代标记,当到达谋而阈值时,就将对象送到养老院,或者某一次回收发现某个对象很大,就直接送进养老院,不浪费复制资源

老年代采用标记-整理算法:

分代收集针对对象存活率采用不同算法:

下面的关于各垃圾回收器就不写:关键词:枚举根节点时的GC停顿STW,jdk1.9默认G1回收器,尽可能的缩短垃圾回收时对用户线程时间的占用,或者提高吞吐量高效能利用cpu执行能力

理解GC日志

JAVAd的自动内存管理:解决对象内存的分配和对象内存的回收:对象分配与所在收集器相关,但都符合一下几条规则

  • 优先在Eden分配,当eden不够时发生minorGC
  • 大对象会直接进入老年代
  • 长期存货的对象在某个GC中进入老年代(默认15岁)
  • 如果在survivor中有大于一半的内存对象年龄相同,则在下一次回收中直接送进养老院:动态对象年龄判定
  • 空间分配担保
  • minorGC的冒险与改判为FULLGC

 

 

                 

                  

                 

               

posted @ 2018-11-19 21:38  异或门  阅读(103)  评论(0编辑  收藏  举报