内存模型与垃圾回收的基本知识

Java的自动内存管理

  1. 垃圾回收两个派别 -> 手动管理/自动管理

  2. 自动管理两个派别 -> 引用计数/标记清除
    引用计数: 看每个对象被引用的次数,如果是0
    的话(没有任何引用),则清除,注意任何被它引用
    的对象的计数要减1

    引用计数的最大问题在于无法处理 循环引用

    标记清除: 事先定义好root,然后链子不断延伸
    没有被链到的对象都是垃圾(大多数语言所采用,JS/python/Java…)

  3. 内存碎片化问题 任何干净的内存都无法容纳新的大对象,需要做内存压缩

  4. 内存管理 = GC + 内存压缩

引用类型、GC基本原理

  1. 引用的类型

    • 强引用/strong reference: 命令式语句都是强引用
    • 软引用/soft reference: 内存不够的时候会回收它们
    • 弱引用/weak reference: 一有GC就回收它们
    • 影子引用/phantom reference: 只能拿到影子,拿不到引用本身
    • SoftRefernce/WeakReference等 都定义在 java.lang.ref里面
  2. 垃圾是如何产生的

    • 在main方法调用foo方法,main的栈帧新增foo的栈帧,heap里面new Object对象,
    • 对象地址指到foo栈帧
      第一步
    • foo执行完以后,foo的栈帧被销毁,但heap里面的Object对象还存在,就变成了垃圾
      第二步
  3. GC的原理

    • 从GC roots(确定不是垃圾)出发,做可达性分析,一直到头,剩下的就是垃圾
  4. GC roots

    • 活的线程/java.lang.Thread
    • 类的静态成员
    • 线程方法栈所引用的对象
      • 说明/线程本身也是GC root
    • JNI/java native interface引用的对象
      • JNI: 通过接口调用C代码
    • 分代GC时其他代的对象
  5. GC发生了什么

    1. stop the world(STW): 所有线程停下
    2. 清除垃圾
    3. 压缩内存(老年代)
    4. copy(新生代)
  6. 对象的分代假设

    • 对象都是用完即弃的,生命周期很短
    • 内存的分代
      1. 年轻代/yong generation
      2. 老年代/tenured
      3. 永久代/permanent generation
  7. 年轻代

    1. 伊甸园/Eden
      无论何时,new一个对象的时候都会i出现在伊甸园中
      可分为多个Thread Local Allocation Buffer/TLAB
      多线程访问共享内存,要么加锁,要么分为独立的小区域(TLAB选择后者)
      TLAB有上限,如果超多则分配common area,要加锁 \

    2. Survior(S0/S1)
      Yong GC发生时,整个年起代进入其中一个Survior区
      比如Eden满了以后,会发生yong GC,所有的非垃圾进入到两个survivor
      中的一个,下一次的GC会进入另外一个Survivor,任何时间只有一个survivor
      有东西,另一个是空的

      足够老的对象被提升到老年代(超过15次GC以后) \

  8. 老年代

    • 年龄‘偏大’,发生GC的频率低,清除垃圾,压紧收缩
  9. 永久代(java 8-)/元空间(java 8+)

    • 永久代: 是堆的一部分,存储类数据,字符串常量
    • OOM(out of memory)一般原因有两个: 自定义ClassLoader和动态字节码生成
    • 元空间: 不是堆的一部分,除非特殊指定,否则没有上限, -XX:MaxMetaspaceSize
  10. GC的种类

    • Minor GC/Yong GC
      • 总是发生在Eden满的时候
      • 会发生STW
    • Major GC/Full GC
      • Major GC清除老年代: 如果对象过大,直接放入老年代
      • 这样是不好的,需要把新生代的内存调大一些
      • Full GC清除整个堆
  11. 分析OOM

    1. terminal: jps 看到进程号
    2. jmap -dump:live,format=b,file=`pwd`/process_id.hprof process_id
  12. GC算法

    • 看图
    • JVM option: -XX代表hotspot专有的,+UseSerialGC里面的+代表开启,-代表关闭
  13. 垃圾回收的过程 -XX:PrintGCDetails -XX:PrintGCDataStamps -XX:PrintGCTimeStamps