Java内存模型与垃圾回收

Java内存模型

  • 存储对象数据
  • Eden区\新生代
  • s0区(from)\新生代
  • s1区(to)\新生代
  • tenured区\老年代

  • 解决程序运行问题,即程序如何执行,或者说如何处理数据
  • 存储局部变量,引用

主要有三部分组成:

  • 局部变量表:用于函数报错的参数及局部变量
  • 操作数栈:保存计算过程的中间结果,作为计算过程的变量临时空间。
  • 帧数据区:异常处理表

方法区 (所有线程共享,永久区)

  • 辅助堆栈的快永久区,解决堆栈信息的产生
  • 存放类信息,常量信息,常量池信息,包括字符串字面量和数字常量。类过多可能会溢出。

GC

垃圾收集算法

引用计数法

  • 思想:在被其他对象引用的时候引用计数器+1,引用失效时引用计数器-1。引用为0对象被回收。
  • 算法弊端:无法处理循环引用的场景(递归对一个对象引用多次)

标记清除算法

  • 思想:对没有引用的对象进行标记,GC进行的时候,若发现对象被标记则进行回收
  • 算法弊端:由于对象的在内存中是随机分部,回收之后会产生内存碎片。

复制算法(新生代)对象存活时间短

  • 思想:将内存分为2块,每次使用其中一块,GC进行时将含有引用的对象复制到未使用的那片内存区,然后垃圾收集器回收当前使用的内存区。如此反复的复制被引用的对象,清除无引用的对象被称为复制算法。(Java中的中S0内存区和S1内存区则是使用这种思想。)

标记压缩法(老年代)对象存活时间长

  • 老年代比较稳定,对象存活时间长,标记压缩法在标记清除法上做了优化,将存活的对象压缩到内存一侧,然后清除无用对象。

分代算法:

  • 根据对象的特点,把内存分为老年代和新生代

分区算法(G1):

  • 将内存区划分为多个小的分区,GC进行时,可以对每个小的分区回收,减少GC时的停顿时间。

对象如何进入老年代:

  • 对象年龄达到一定大小则离开新生代进入老年代,对象年龄由GC次数决定,可以设置JVM参数(-XX:MaxTenuringThreshold)来设置年龄大小,大对象

TLAB:

  • Thread Local Allocation Buffer(线程本地分配缓存器)(栈上分配)线程专用的内存区域,为了加速对象的分配产生的。一般不会太大,当大对象不能在TLAB上分配时,就分配到堆上。

创建对象内存分配过程:

  • 栈上分配(若失败进入下一步,若成功结束流程)—》在TLAB上分配(若失败进入下一步,若成功结束流程)—》是否满足进入老年代(若失败进入下一步,若成功结束流程)—》Eden分配(结束)

垃圾回收器

串行垃圾回收器(单线程):SerialGC

并行垃圾回收器(多线程):

  • ParNew(新生代),
  • CMS(并发标记清除)回收器,当达到阈值进行回收内存,默认阈值为: 68%
  • G1 分代+分区 思想
    原文作者:java内存模型
    原文地址: https://blog.csdn.net/qq_24489717/article/details/78578450
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞