java内存结构及垃圾回收算法介绍

java 内存结构是逻辑存储结构,与内存模型不是一个概念

jvm有三部分组成

  • 堆,
  • 方法区(其实也是堆,只不过是逻辑分区,元空间(使用直接内存),1.8以前叫永久代(以前实际上是与堆隔离开的,物理上连续空间))
  • 栈(程序计数器、本地方法栈、虚拟机栈组成)

  • 由线程共享,存放 new 出来的对象,是垃圾回收器的主要工作区域。

方法区

线程共享,实际使用的是堆内存,存放已被加载的类的元数据(方法代码,方法名、返回值、访问权限等)、常量池、静态变量、即时编译器编译后的代码等信息,最后会在堆中创建一个Class对象,方法区中的元数据,可以通过Class对象访问,JDK 1.8 中方法区被元空间取代,使用直接内存

 不过元空间与永久代最大的区别在于元空间不在虚拟机设置的内存中,而是使用本地内存

方法区的理解 :元空间、永久代是方法区具体的落地实现。方法区看作是一块独立于Java堆的内存空间,它主要是 用来存储所加载的类信息的。 

  • 线程私有,分为 Java 虚拟机栈和本地方法栈,存放局部变量表、操作栈、动态链接、方法出口等信息,方法的执行对应着入栈到出栈的过程。

  • 本地方法栈:native关键字,凡是被native修饰的方法,都会去调用底层的非java语言的库

  • 程序计数器:程序执行的时候,程序计数器是有值的,其记录的是程序正在执行的字节码的地址

 垃圾回收

垃圾回收主要针对堆中的对象,堆的细分结构如下

新生代 (eden survivor0 survivor1 )

老年代

元空间(方法区,类元数据信息、串常量池、静态变量

  • 发现无用的信息对象

  • 回收被无用对象占用的内存空间,使空间再次可被程序使用

堆中内存分配比例

新生代 :老年代  1:2

新生代 Eden:survivor0 :survivor1  8:1:1

垃圾回收算法

垃圾回收主要发生在堆,主要是回收内存无用的对象,本质是产生连续空间供给其他对象使用

四种引用关系与垃圾回收(强软弱虚)

强引用: 如 Object object= new Object(); 一个对象具有强引用,就不会被垃圾回收器回收。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止

引用在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围进行第二次回收对象,用来描述一些还有用但并非必需的对象,使用SoftReference表示

弱引用:JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用WeakReference来表示

虚引用:这个对象被收集器回收时收到一个系统通知最弱的一中引用关系,不能通过虚引用来取得一个对象实例,用PhantomReference表示

GC判断该对象是否被回收

  • 引用计数: 对象被引用的时候,计数器加1,当计数器为0的时候代表对象可以被回收。

  • 可达性分析: 从GC Roots向下搜索,也就是从根对象往下搜索,经过的地方为引用链,如果对象不在引用链,则代表可被回收

可达性分析的GC Roots

  • 虚拟机栈局部变量表中引用的对象
  • 方法区中类静态属性引用的对象、常量引用的对象
  • 本地方法栈中JNI(native方法)引用的对象

以上这些根节点是垃圾收集器在进行可达性分析时的起始点,它会从这些根节点出发,沿着对象引用关系向下搜索,形成可达的对象图。如果一个对象无法从任何根节点通过引用链到达,则认为它是不可达的,可以被垃圾回收器当作垃圾来处理

三色标记算法(tri-color-marking)

三色标记算法(tri-color-marking),是一种常见的垃圾收集的标记算法,属于可达性分析算法的一部分,常用于垃圾收集器CMS和G1

三色标记算法将每个节点归纳分类为三类:白色节点、灰色节点和黑色节点。三色标记算法采用深度优先搜索的策略

  • 白色:可达性分析初始阶段,每个节点初始颜色都是白色(默认的),表示该节点还没被GC扫描过。如果可达性分析结束之后,节点仍然是白色,这表示该节点没有被引用,正常情况下是可以被GC回收
  • 灰色:表示该节点至少还有一个引用节点未被扫描过,这样的节点会被标记成灰色节点。
  • 黑色:GC扫描过的节点节点会被标记成黑色节点,黑色节点表示存活对象,GC是不能回收的

此处标记算法详细图解,请参考文章三色标记算法

复制法

先暂停程序的运行,然后将所有存活的对象从当前的堆复制到另一个堆,没有被复制的全部都是垃圾,当对象被复制到新的堆的时候,它们是一个挨着一个的,所以新堆保证紧凑排列,然后就可以按照上面的方法简单的分配新的空间了

标记-清除算法

分为两个阶段,一个是标记阶段,这个阶段内,为每个对象更新标记位,检查对象是否死亡;第二个阶段是清除阶段,该阶段对死亡的对象进行清除,执行 GC 操作。

  • 是可以解决循环引用的问题
  • 必要时才回收(内存不足时)
  • 会产生内存碎片

标记—整理法

标记-整理法是标记-清除法的一个改进版。同样,在标记阶段,该算法也将所有对象标记为存活和死亡两种状态;不同的是,在第二个阶段,该算法并没有直接对死亡的对象进行清理,而是将所有存活的对象整理一下,放到另一处空间,然后把剩下的所有对象全部清除。这样就达到了标记-整理的目的,不会产生内存碎片

分代算法

不同的对象生命周期是不一样的。因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率

  • 在新生代,每次垃圾收集器都发现有大批对象死去,只有少量存活,采用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。
  • 而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须“标记清除法或者标记整理算法进行回收。

详细了解jvm算法及优化:jvm详解包含垃圾回收以及jvm参数优化

GC安全点

Java虚拟机(JVM)中的垃圾回收(GC)安全点(Safe Point)是指程序执行时的一个特定位置,在这个位置上,所有线程都处于已知且一致的状态,此时JVM可以安全地进行垃圾回收或者其他操作

安全点选择 

 安全点的选定通常发生在以下几种情况下:

  • 程序执行过程中遇到“同步块”(如MonitorEnter和MonitorExit指令)或者调用方法等“控制流转换”的地方。
  • 当线程处于Idle状态,例如线程调用sleep、wait等方法暂停运行时。
  • 执行JNI(Java Native Interface)函数返回时。
  • 在循环次数较多的代码中,JVM会通过采用“Polling”机制周期性检查是否需要触发GC

简单来说,就是在执行过程中那些具有“天然”暂停特性的位置,以及可以通过主动探测方式快速达到暂停状态的位置,都会被设置为安全点。在这些安全点,JVM可以暂停所有线程,然后开始垃圾回收工作,确保在此期间不会发生对象引用关系的变化,从而保证了GC的正确性和安全性 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值