热门课程

免费试听

上课方式

开班时间

当前位置: 首页 -   文章 -   新闻动态 -   正文

java高阶——深入了解Hotspot

知了堂姐
2024-07-09 11:12:24
0

对象的创建

  • 指针碰撞 : 假设 java 堆中的内存是绝对规整的, 所有被使用过的内存都放到一边, 空闲的内存放在另一边 , 中间放着一个指针作为分界点的指示器 . 那所分配内存就是仅仅把那个指针向空闲空间方向挪动一段与对象大小相等的距离 . 这种分配方法成为”指针碰撞” .
  • 空闲列表 : 如果内存并不是规整的, 已被使用的和空闲的内存交互在一起, 没有办法进行简单的指针碰撞 . 虚拟机就维护一个列表, 记录哪些内存块是可用的, 在分配的时候从列表中找到一块足够大的内存块划分给实例对象, 并更新列表上的记录 . 这种分配方式叫做 “空闲列表”

选用哪种分配方式由 Java 堆是否完整决定, 而 Java 堆是否完整又取决于所采用的垃圾收集器是否带有空间压缩的能力来决定的 . Serial . ParNew 等带压缩整理过程的收集器就使用 指针碰撞 . 基于 CMS 这种清除算法就使用 空闲列表

 

 

并发情况下不是线程安全的 :

  • CAS + 失败重试 保证原子操作
  • 本地线程分配缓冲 ( TLAB ) : 把内存分配的动作按照线程划分在不同的空间之中进行, 即每个 线程在 Java 堆中预先分配一小块内存 ,成为本地线程分配缓冲 ,哪个 线程要分配内存, 就在那个线程的本地缓冲区中分配 .

对象的内存布局

在Hotspot虚拟机里, 对象在堆内存中的存储布局可以分为三个部分 : 对象头 实例数据 对齐填充

对象头包含两部分

  • Mark Word
    • 哈希码 (HashCode)
    • GC分代年龄
    • 锁相关信息 ( 锁状态标志 线程持有的锁 偏向线程 ID )

 

  • 类型指针 : 类型元数据的指针, 来确定它是哪个类的实例
  • 如果对象是数组, 对象头中还有记录数组长度的数据

实例数据即我们代码中定义的各种类型字段的内容

对象的访问定位

创建对象自然是为了后续使用该对象, Java 程序会通过栈上的 reference 数据来操作栈上的具体对象 .

主流的访问方式主要有 句柄直接指针

  • 句柄 : java 堆中将分出一块内存作为句柄池 , reference 中存储的就是对象的句柄地址, 而句柄中又包含了对象实例数据和对象类型数据各自的地址信息 .
  • 直接指针 : reference 中存储的就是对象地址,

 

 

 

使用句柄来访问的最大好处就是 reference 中存储的是 稳定的句柄地址 , 在对象被移动 (垃圾收集时移动对象是非常普遍的) 时只需要改变 句柄 中的实例数据指针, 而reference 本身不需要修改 .

使用直接指针的好处就是速度更快, 他节省了一次指针定位的时间开销 (HotSpot虚拟机主要采取的是这种对象访问定位)

内存分配策略

Java 堆是垃圾收集器管理的主要区域,因此也被称作GC 堆(Garbage Collected Heap).从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代:再细致一点有:Eden 空间、From Survivor、To Survivor 空间等。进一步划分的目的是更好地回收内存,或者更快地分配内存。

堆空间的基本结构:

 

 

Eden 区、From Survivor0(“From”) 区、To Survivor1(“To”) 区都属于新生代,Old Memory 区属于老年代。

大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。

大对象直接进入老年代

大对象就是需要大量连续内存空间的对象(比如:字符串、数组)。

为什么要这样呢? 为了避免为大对象分配内存时由于分配担保机制带来的复制而降低效率。

针对 HotSpot VM 的实现,它里面的 GC 其实准确分类只有两大种:

部分收集 (Partial GC):

  • 新生代收集(Minor GC / Young GC):只对新生代进行垃圾收集;
  • 老年代收集(Major GC / Old GC):只对老年代进行垃圾收集。需要注意的是 Major GC 在有的语境中也用于指代整堆收集;
  • 混合收集(Mixed GC):对整个新生代和部分老年代进行垃圾收集。

整堆收集 (Full GC):收集整个 Java 堆和方法区。

对象已死 ?

引用计数算法 : 在对象中添加一个引用计数器, 每当有一个地方引用它, 计数器加一,当引用失效时, 计算器就减一. 任何时刻计算器为零的对象都不可以再被使用 . (无法解决循环引用)

可达性分析算法: 如果某个对象到 GCRoots 没有任何引用链相连, 或者用图论的话是 从 GCRoots到这个对象不可达, 则证明这个对象是不可能在被使用的 .

 

 

引用计数法

给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。

这个方法实现简单,效率高,但是目前主流的虚拟机中并没有选择这个算法来管理内存,其最主要的原因是它很难解决对象之间相互循环引用的问题。

大家都在看

数据中台是什么

2024-07-09 浏览次数:0

网络安全能找什么工作岗位?网络安全行业高新岗位总...

2024-07-09 浏览次数:0

成都java培训机构有哪些口碑比较好的?

2024-07-09 浏览次数:0

白盒测试是动态还是静态?白盒测试和黑盒测试有什么...

2024-07-09 浏览次数:0

渗透测试面试题及答案详解,助你获得高薪岗位

2024-07-09 浏览次数:0

女生学ui还是前端?女生学IT不再是难事

2024-07-09 浏览次数:0
最新资讯
成都java程序员培训可靠吗?...   成都java程序员培训可靠吗?这个问题是我们找培训机构最看重的,毕竟培训费用也是不便宜的,如果花...
java和web前端哪个好找工...   java和web前端哪个好找工作?很多人都很迷茫,因为看就业情况,Java和前端都是IT行业的热...
成都Java培训课程哪家好?要...   5月23日,是Java27岁的生日,Java作为一门热门的编程语言,一直以来是很多人转行首选语言...
Java培训学什么?只学习Ja...   Java培训学什么?很多想报名Java培训的人都比加关注这个问题,毕竟学费并不低,如果只单单学习...
java培训哪里好?靠谱Jav...   Java培训哪里好?想要找到一个好的、靠谱的Java培训机构,那么一定要记住这些靠谱Java培训...
java培训班学费一般多少?   java培训班学费一般多少?俗话说钱不是万能的,但是没有钱是万万不能的,我们想去参加Java培训...
Java 学习前景如何?探索未...   学Java还有前景吗?这个得看看市场需求:  根据2020年TIOBE开发语言排行榜宣布的流行开...
当兵两年,回来继续学Java   当兵两年,回来继续学Java  人这一生就像一部半开放式结局的电影,有大致的时间线,却没有准备好...