文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java内存分配与回收机制是什么

2023-06-03 14:34

关注

本篇内容介绍了“Java内存分配与回收机制是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一.运行时数据区域

下图是Java虚拟机运行时的内存示意图:

Java内存分配与回收机制是什么

从图中我们可以看到Java内存总共分为6个部分:

  1. 程序计数器:每条线程都有一个独立的程序计数器,计数器可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时,就是通过改变这个计数器的值来选取下一条所需执行的字节码指令、分支、循环、跳转、异常处理,线程恢复等基础功能都需要依赖这个计数器完成。

所以通过表格的形式概括如下:

数据区域 概括 线程共享 程序计数器 当前线程所执行的字节码的行号指示器 否 虚拟机栈 为Java方法执行创建栈帧存储局部变量、操作数栈、动态链接、方法出口等信息 否 本地方法栈 与虚拟机栈类似,为Native方法服务 否 堆 存放对象实例 是 方法区 存储虚拟机已加载的类信息、常量、静态变量、即时编译后的代码等数据 是 运行时常量池 方法区的一部分,存放编译期生成的字面量和符号引用 是 直接内存 被分配在堆外的内存,性能高,不受Java堆的大小限制 是 二.对象的创建与内存布局

对象的创建

Java内存分配与回收机制是什么

Java对象的创建

上图是对象创建的完整流程图,接下来做详细说明。

  1. 当虚拟机收到new指令后,检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用所代表的类是否已被加载、解析和初始化过。如果没有,必须先执行类加载过程。

对象的内存布局

Java内存分配与回收机制是什么

对象的内存布局总共分为三个部分:

  1. 对象头中主要包括两部分信息:

  1. 实例数据部分是对象真正存储的有效信息,也是程序代码中定义的各种类型的字段内容。从父类继承下来的,在子类中定义的都需要记录下来。

  2. 对齐填充仅仅起到占位符的作用。HotSpot VM的自动内存管理系统要求对象起始地址是8字节的整数倍,所以对象大小必须是8字节的整数倍。当对象实例数据部分没有对齐时,需要通过对齐填充来补

在此我向大家推荐一个Java高级群 :725633148 里面会分享一些资深架构师录制的视频录像:(有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构、面试资料)等这些成为架构师必备的知识体系 进群马上免费领取,目前受益良多!

三.内存的回收

对象存活判定

Java虚拟机通过可达性分析来判定对象是否存活。这个算法的基本思想是通过一系列称为"GC Roots"的对象作为起始点,从这些节点向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有与任何引用链相连时,则该对象是不可用的。

如图,object5,object6,object7虽然互有关联,但是GC Roots是不可达的,所以它们被判定是可回收的对象。

另外值得一提的是引用计数算法,引用计数法是通过给对象一个引用计数器,每当有一个地方引用它时,计数器值就加一;引用失效时,计数器值就减一;任何时刻计数器为0的对象就是不可能再被使用的。引用计数器效率高、实现简单。但是很难解决对象间相互循环引用的问题,主流Java虚拟机几乎都不再使用引用计数法来管理内存。

Java内存分配与回收机制是什么

可达性分析示意图

即使在可达性分析算法中不可达的对象,也不一定会立即被回收。一个对象被回收,至少要经历两次标记过程。

如果对象在进行可达性分析后没有与GC Roots相连的引用链,那它将会被第一次标记并进行一次筛选。筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或finalize()方法已被虚拟机调用过,虚拟机将这两种情况视为"没有必要执行"。

如果这个对象判定为有必要执行finalize()方法,那么这个对象会放置在F-Queue队列中,稍后由虚拟机自动建立、低优先级的Finalizer线程去执行finalize()方法。GC对F-Queue中的对象进行第二次小规模标记,如果对象重新与引用链上的任何一个对象建立关联,那么第二次标记时它将被移除"即将回收"的集合。否则对象就真的要被回收了。

Java内存分配与回收机制是什么

Finalize方法

方法区回收判定

方法区的回收主要包括两部分内容:废弃常量和无用的类。

垃圾收集算法

  1. 标记-清除算法(Mark-Sweep):

  2. 算法分为"标记"和"清除"两个阶段:首先标记出需要回收的对象,在标记完成后统一回收被标记的对象。它主要不足有两个:一是效率问题,标记和清除两个过程效率都不高。二是空间问题,标记清除后会产生大量不连续内存碎片,碎片太多可能导致要分配较大对象时,无法找到足够的内存空间不得不提前触发一次垃圾收集动作。

Java内存分配与回收机制是什么

  1.  

  2. 标记-清除

  3. 复制算法:

  4. 复制算法将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当一块内存用完了,将存活的对象复制到另一块上面,然后把已使用的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。只是这种算法将内存缩小为原来的一半,代价较高。

Java内存分配与回收机制是什么

  1.  

  2. 复制算法

  3. 标记-整理算法(Mark-Compact):

  4. 标记过程与"标记-清除"算法一样,但后续不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存

Java内存分配与回收机制是什么

  1.  

  2. 标记-整理算法

分代收集算法

商业虚拟机的垃圾收集都采用分代收集算法,根据对象存活周期将内存划分为几块。Java堆分为新生代和老年代,这样可以根据年代特点采用适当的收集算法。新生代中每次垃圾收集都有大批对象死去,那就选用复制算法。老年代对象存活率高,没有额外空间进行分配担保,适合使用"标记-清理"或"标记-整理"算法来回收。

内存分配与回收策略

  1. 对象优先在Eden分区:

  2. 大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间分配时,虚拟机发起一次Minor GC。GC后对象尝试放入Survivor空间,如果Survivor空间无法放入对象时,只能通过空间分配担保机制提前转移到老年代。

  3. 大对象直接进入老年代:

  4. 大对象指需要大量连续内存空间的Java对象。虚拟机提供-XX:PretenureSizeThreshold参数,如果大于这个设置值对象则直接分配在老年代。这样可以避免新生代中的Eden区及两个Survivor区发生大量内存复制。

  5. 长期存活的对象进入老年代:

  6. 虚拟机会给每个对象定义一个对象年龄计数器。如果对象在Eden出生并且经过一次Minor GC后任然存活,且能够被Survivor容纳,将被移动到Survivor空间中,并且对象年龄设为1.每次Minor GC后对象任然存活在Survivor区中,年龄就加一,当年龄到达-XX:MaxTenuringThreshold参数设定的值时,将会移动到老年代。

  7. 动态年龄判断:

  8. 虚拟机不是永远要求对象的年龄必须达到-XX:MaxTenuringThreshold设定的值才会将对象移动到老年代去。如果Survivor中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代。

  9. 空间分配担保:

  10. 在Minor GC前,虚拟机会检查老年代最大可用连续空间是否大于新生代所有对象总空间,如果条件成立,那么Minor GC是成立的。如果不成立,虚拟机查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用连续空间是否大于历次移动到老年代对象的平均大小,如果大于,将尝试一次Minor GC。如果小于,或者HandlePromotionFailure设置值不允许冒险,那将进行一次Full GC。

新生代GC(Minor GC):发生在新生代的垃圾收集动作,因为Java对象大多朝生夕死,所以Minor GC非常频繁,回收速度也较快。

老年代GC(Major GC/Full GC):发生在老年代的垃圾收集动作。出现Major GC,经常会伴随至少一次Minor GC。Major GC的速度一般比Minor GC慢10倍以上。

“Java内存分配与回收机制是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯