JVM垃圾回收(一)(引用计数法,可达性分析算法)

垃圾回收

1. 如何判断对象可以回收

1.1引用计数法
  • 如果一个对象被引用了 计数+1,如果某一个对象不再引用它了-1;如果这个对象的计数变为0,那边它就会被回收;
  • 存在问题 循环引用
    JVM垃圾回收(一)(引用计数法,可达性分析算法)_第1张图片
1.2 可达性分析算法
  • 首先确定根对象(不能被垃圾回收的对象),在垃圾回收之前,先对堆中的所有对象扫描,check每一个对象是不是被根对象直接或者间接的引用,如果是这个对象不能被引用,反之将被回收;
  • Java虚拟机中的垃圾回收器采用可达性分析算来探索所有存活对象
  • 扫描堆中的对象,看是否能够沿着GC Root对象为起点的引用链找到该对象,找不到,表示可以回收
  • 哪些对象可以作为GC Root?(可以借助eclipse 提供的 Memory Analyzer 查看GC Root对象)
    • System Class 核心系统类所引用的Java对象;
    • Native Class 操作系统方法所引用的Java对象;
    • Thread 活动线程中引用的对象;
    • Busy Monitor 被加锁的对象;
  • jmap -heap pid 查看进程堆内存结构
  • jmap -dump:format=b,live,file=aaa.bin pid(fromat 表示抓取格式 b:二进制,live:只关心存活的对象,在使用live之前会执行一次垃圾回收,file:存放的文件)
1.3 五种引用

JVM垃圾回收(一)(引用计数法,可达性分析算法)_第2张图片

  1. 强引用

    • gc 不会回收强引用对象;
  2. 软引用

    • gc回收后内存还是不够,会回收软引用对象;
  3. 弱引用

    • 只要发生了gc 不管内存是否充足,都会回收弱引用对象;

    注意:软,弱引用本身也是一个对象,如果配备了引用队列,当软引用所引用的对象被垃圾回收后,软引用和弱引用会进入引用队列

  4. 虚引用

    • referenceHandler 会监控队列,如果虚引用对象所引用的对象被回收,它会进入队列
    • 典型用法 Cleaner 所引用的 ByteBuffer 被回收后 Cleaner会进入引用队列,referenceHandler 监控到了Cleaner进入引用队列,调用Cleaner的clean方法,调用Unsafe.freeMemory();释放直接内存;
  5. 终结器引用

    • Object对象有一个finalize(); 终结方法,当一个对象重写了终结方法,并且没有对象强引用它,就会被垃圾回收;

    注意:软,弱引用可以不配备引用队列,但是虚引用,终结器引用必须配合引用队列;
    JVM垃圾回收(一)(引用计数法,可达性分析算法)_第3张图片

你可能感兴趣的:(jvm,java,开发语言)