深入理解java虚拟机

JAVA虚拟机

  • 生命周期:随着程序的启动而诞生,随着程序的关闭而死亡
  • 类型:
    • 守护线程
    • 非守护线程
  • 运行时数据区
    • 堆:内存共享区域。(jdk7之后将方法区的常量池移植到堆)
    • 方法区
    • 虚拟机栈
      • 本地方法栈
      • java虚拟机栈
    • 程序计数器

判断对象是否存活的方法

  • 引用计数法

    • 为每一个对象分配一个引用计数器,每当有一个地方引用他,引用计数器加一,当一个引用失效,引用计数器减一。直到引用计数器清零,意味对象不在存活
  • 可达性分析算法

    • 将一系列的”GC Roots”根对象作为起始节点集,以这些起始节点集开始,根据引用关系,向下搜索,走过的路径称为“引用链”,当”GC Roots”到某个对象是不可达的,那么判定这个对象不在存活

引用的四大类型

  • 强度依次递减
    • 强引用 new 出来的对象,只要强引用关系存在,JVM永远不会回收
    • 软引用 使用SoftReference类实现,对于软引用来说,当系统内存不够时才会被回收
    • 弱引用 使用WeakReference类实现,只要垃圾回收机制执行便会回收
    • 虚引用 使用phantomReference类实现,必须联合引用队列使用。主要作用跟踪对象被垃圾回收的状态

内存溢出

  • java堆溢出:java堆用于存储实例对象,当我们不断创建对象,并且保证”GcRoots”与对象有引用链关系,不被gc回收,那便会导致java堆溢出
  • java栈溢出
    • 当线程请求的栈深度大于虚拟机的最大深度,将会抛出stackoverflowError。
      • 通俗来讲,每执行一个方法,就会创建一个栈帧,当虚拟机的栈容器无法容纳新的栈帧,那么便会抛出StackOverflowError
    • 当栈是允许可动态扩展的栈,当无法申请到足够的内存,将会抛出OOM
      • Hotspot虚拟机不支持动态扩展内存,所以只会出现当线程请求的栈深度大于虚拟机的最大深度才会抛出OOM

判断一个类是否不再被使用

  • 该类的所有实例已经被回收
  • 该类的类加载器已经被回收
  • 该类对应的java.lang.class对象没有在任何地方被引用

分代收集理论

  • 弱分代假说:所有对象都是朝生夕灭

  • 强分代假说:熬过多次垃圾收集的对象越难消亡

  • 结合分代收集理论,java虚拟机将堆分为新生代和老年代

  • 收集的两种方法

    • 部分收集:目标不是完整收集整个JAVA堆的垃圾集
      • 新生代收集(minor/young GC):目标只是新生代的收集
      • 老年代收集(major/old GC):目标老年代收集
      • 混合收集(mixed GC):目标整个新生代和部分老年代的收集
    • 整堆收集:目标为全体Java堆和方法区的垃圾收集
  • 收集算法

    • 标记-收集算法:先标记要回收的对象,标记完成后,统一收集。
      • 缺点:
        • 如果堆中包含大量需要收集的对象,那么先全部标记再全部清除,效率低下。
        • 标记清除会产生大量不连续的碎片,碎片太多以后要分配太大的对象无法找到连续内存
  • 复制算法:将内存区域均等划分为两块区域,每次只使用一块,当内存快使用完后,将存活的对象复制到另外一块内存中,再一次性清理已使用的内存,

    • 缺点:
      • 每次只能使用一半内存
      • 当大量对象存活时,会产生大量内存复制的开销
      • 标记-整理算法:在标记收集的基础上,标记完后,把剩余存活的对象移动到一端。然后清理端边界外的对象
  • 新生代复制算法

    • 目前大部分JVM对新生代都采取复制算法,因为每次新生代回收对象,都要大量回收,因此复制的工作量比较少,然而他们并不是内存1:1分割新生代。而是将内存划分为8/10的Eden区和两块共占2/10的survivor空间(from Space,To Space)。每次使用只使用Eden区和其中一块的survivor空间,当要进行回收时,将存活对象移动到另一块(To Space)空间,再进行对象回收
  • 老年代标记整理算法

    • 老年代需要回收的对象量少,先标记,再将存活对象移至内存一端,在进行清理
    • 新生代对象绝大多数分配在Eden和From Space空间,少部分大对象直接分配在老年代。
    • 当Eden和From Space空间不足会发生一次GC.将Eden和From Space空间存活对象移动到To Space空间,再进行对象回收。
    • 当对象在Survivor区躲过一次GC后,其年龄就会+1。当年龄达到15岁。便会存入老年代中。
-------------The End-------------
0%