垃圾回收机制

笔记。

Posted by AnAn on November 3, 2020

java内存分为 堆 栈 方法区

  • 堆区:

    1. 存储的全部是对象 ,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
    2. jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
  • 栈区:
    1. 每个线程包含一个栈区 ,栈中 只保存基础数据类型的对象和自定义对象的引用(不是对象) ,对象都存放在堆区中
    2. 每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问 。
    3. 栈分为3个部分: 基本类型变量区、执行环境上下文、操作指令区(存放操作指令) 。
  • 方法区:
    1. 又叫 静态区 ,跟堆一样, 被所有的线程共享 。方法区 包含所有的class和static变量 。
    2. 方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

      java引用类型

  • 强引用
  • 即java中不同的引用,该类型即使内存不足,也不会被释放
     String str = "abc";  
     List<String> list = new Arraylist<String>();  
     list.add(str);  
    
  • 软引用
    • 使用SoftReference类间接的引用,在内存不足时,会将其作为可回收对象释放
      A a = new A();              
      SoftReference<A> sr = new SoftReference<A>(a);    
      
  • 弱引用
    • 使用WeakReference类间接引用,GC触发时便会被回收
      Object c = new Car(); //只要c还指向car object, car object就不会被回收  
      WeakReference<Car> weakCar = new WeakReference(Car)(car);  
      
  • 虚引用
    • 若对象被回收时将会把虚引用加入到于对象关联的引用队列

      类加载器

  • Bootstrap(启动引导)加载器
  • EXt(扩展)加载器
  • APP(系统)加载器
  • 自定义加载器

    类的生命周期

    1. 加载:获取类的二进制字节流;生成方法区的运行时存储结构;在内存中生成Class对象
    2. 验证:确保该Class字节流符合虚拟机要求
    3. 准备:初始化静态变量
    4. 解析:将常量池的符号引用替换成直接引用
    5. 初始化:执行静态代码,变量赋值
    6. 使用
    7. 卸载

判定是否为垃圾的方法

  • 引用计数法
  • 可达性分析法:
    定义:从 GC ROOT 开始搜索,不可达的对象都是可以被回收的
  • GC ROOT:
    1.虚拟机栈/本地方法栈中引用的对象
    2.方法区中常量/静态变量引用的对象

    垃圾处理机制

    1. 标记清除法:
      直接对可回收对象删除,这样的做法会产生大量内存碎片
    2. 标记复制法:
      将内存空间划分为两部分,永远保持一部分是空的,先将存活对象复制到一侧,然后将另一侧清空,这样做内存浪费,相当于只有一半内存可用
    3. 标记压缩法:
      将可回收对象清理后,在将存活对象移动。使其空间连续,效率较低。
    4. 分代回收(jvm使用的):
    • 将内存分为青年代,老年代,永久代三个区。
    • 对于青年代又可分为to(s1) from(s0) eden
    • 将eden区,s0,s1区相结合使用标记复制法,即eden区满了(将存活对象)移动到s0区,s0区满了移动到s1区。
    • 经过多代(大约7代)后将仍然存活的s1区对象移动到老年区,老年区使用复制压缩法。老年区满后使用标记复制法移动到永久区。