首页 > 其他分享 >JVM指针压缩实现原理

JVM指针压缩实现原理

时间:2024-11-06 20:59:18浏览次数:2  
标签:字节 对象 32 压缩 64 JVM 指针

JVM指针压缩实现原理

   概要

   Java 中的指针压缩(Pointer Compression)是一个与内存管理相关的优化技术,主要应用于 JVM 的对象引用(即指针)的存储方式。指针压缩的目标是减少对象引用占用的内存空间,从而提高内存利用效率,特别是在 64 位系统上。

   一、对象的内存布局

   在了解指针压缩之前,需要先搞懂java的实例对象在JVM虚拟机中内存结构是什么样的。

   在Hotspot虚拟机中,对象在内存中的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

   1. 对象头(Header)
对象头,又包括三部分:MarkWord、元数据指针、数组长度。
下面图是64位系统下的对象头布局

MarkWord:用于存储对象运行时的数据,比如HashCode、锁状态标志、GC分代年龄等。这部分在64位操作系统下,占8字节(64bit),在32位操作系统下,占4字节(32bit)。
具体的作用可以参考我之前写的synchronized锁原理分析(一、从Java对象头看synchronized锁的状态)

指针:对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
这部分就涉及到一个指针压缩的概念,在开启指针压缩的情况下,占4字节(32bit),未开启情况下,占8字节(64bit),现在JVM在1.6之后,在64位操作系统下都是默认开启的。

数组长度:这部分只有是数组对象才有,如果是非数组对象,就没这部分了,这部分占4字节(32bit)。

2、实例数据(Instance Data)
用于存储对象中的各种类型的字段信息(包括从父类继承来的)。

3、对齐填充(Padding)
java对象的大小默认是按照8字节对齐,也就是说java对象的大小必须是8字节的倍数。如果算到最后不够8字节的话,那么就会进行对齐填充。
比如:对象头+对象体大小不是8字节的倍数,则通过该部分进行补齐,比如对象头+对象体大小只有30字节,则需要补齐到32字节,这里的对齐填充就是2字节。

二、指针压缩

1. 为什么要指针压缩

计算机操作系统分32位和64位,这里的位在计算机里是用0和1来表示的,用32个(或64个)二进制0和1的组合来表示内存地址。以32位为例,在普通的内存中,对象的大小最小是以1字节来计算的,通过0和1的排列组合,能够表示寻址的内存空间最大就是2^32个,换算成内存空间就是2 ^ 32 / 1024 / 1024 / 1024 = 4G,也就是说32位的操作系统最大能寻址的内存空间只有4G。同理,64位的操作系统最大能寻址的内存空间就更大了。

但是当我们准备将32位系统切换到64位系统,起初我们可能会期望系统性能会立马得到提升,但现实情况可能并不是这样的,为什么呢?


1)增加了GC开销
64位对象引用需要占用更多的堆空间,留给其他数据的空间将会减少,从而加快了GC的发生,更频繁的进行GC。


2)降低CPU缓存命中率

64位对象引用增大了,CPU能缓存的oop将会更少,从而降低了CPU缓存的效率。


既然32位系统内存不够,64位内存够但又影响性能,那有没有折中方案来解决这两个问题呢,于是聪明的JVM开发者想到了利用压缩指针,在64位的操作系统中利用32位的对象指针引用获得超过4G的内存寻址空间。


2. 如何压缩指针

在 JVM 中,对象的内存地址总是 8 字节对齐,即每个对象的地址都是 8 的倍数,这意味着其二进制表示的末尾 3 位始终为 0。指针压缩正是利用了这一特点,省略了这些无意义的 0 位:

压缩存储:使用 32 位来存储指针(而非 64 位),省去末尾的 3 个 0,从而节省空间。
地址还原:当 JVM 需要访问对象时,通过将这个 32 位指针左移 3 位来恢复完整的 64 位地址。
这种方式扩展了可寻址的内存空间,使得 32 位指针可表示 2^35(约 32GB)的内存地址,从而在 64 位系统上为 JVM 节省内存并满足大部分应用需求。

3. JVM指针压缩参数

关于压缩指针的两个参数:
UseCompressedClassPointers:压缩类指针
UseCompressedOops:压缩普通对象指针
Oops是Ordinary object pointers的缩写,这两个参数默认是开启的,即-XX:+UseCompressedClassPointers,-XX:+UseCompressedOops,也可手动设置,如下所示

2位HotSpot VM是不支持UseCompressedOops参数的,只有64位HotSpot VM才支持。
Oracle JDK从6 update 23开始在64位系统上会默认开启压缩指针。

三、总结

通过指针压缩,利用对齐填充特性,通过映射方式达到了内存地址扩展的效果
指针压缩能够节省内存空间,同时提高了程序的寻址效率
堆内存设置最好不要超过32GB,这时指针压缩将会失效,造成空间的浪费
指针压缩不仅可以作用于对象头的类型指针,还可以作用于引用类型的字段指针(包括引用类型的数组指针)
-XX:ObjectAlignmentInBytes,默认是 8,也就是 8 字节对齐


参考链接:

https://blog.csdn.net/liujianyangbj/article/details/108049482
https://www.cnblogs.com/star95/p/17512212.html

标签:字节,对象,32,压缩,64,JVM,指针
From: https://www.cnblogs.com/hld123/p/18531018

相关文章

  • 【算法】【优选算法】双指针(下)
    目录一、611.有效三⻆形的个数1.1左右指针解法1.2暴力解法二、LCR179.查找总价格为目标值的两个商品2.1左右指针解法2.2暴力解法三、15.三数之和3.1左右指针解法3.2暴力解法四、18.四数之和4.1左右指针解法4.2暴力解法一、611.有效三⻆形的个数题目链......
  • 利用本地docker镜像压缩包部署若依前后端分离框架
    前言:利用本地docker镜像压缩包部署若依前后端分离框架(制作镜像压缩包看上一篇文章),掌握docker基本操作,熟悉若依前后端分离部署一、部署环境1、把所需压缩包上传到ubuntu上,并加载为docker镜像链接:https://pan.baidu.com/s/15b2FkhUZhYECuGoClbltVg提取码:mv3h分别执行......
  • 使用双指针技术去除ArrayList中的重复元素
    技术博客:使用双指针技术去除ArrayList中的重复元素在Java编程中,处理集合数据时,去除重复元素是一个常见的需求。本文将介绍如何使用双指针技术来高效地去除ArrayList中的重复元素,并通过两种不同的方法进行实现。1.问题背景假设我们有一个包含重复元素的ArrayList,例如:ArrayL......
  • 252 摸鱼 压缩dp
    /*http://oj.daimayuan.top/course/5/problem/252蜗蜗一共有n天假期,在假期的第i天摸鱼他会得到ai的快乐值。如果蜗蜗每天都摸鱼的话,他会有愧疚感,所以蜗蜗制定了这么个计划:对于每一天,蜗蜗都有一个列表,如果蜗蜗在列表中的每一天都在摸鱼的话,这一天蜗蜗就不能摸鱼。现在请问......
  • 《JVM第8课》垃圾回收算法
    为什么要进行垃圾回收?垃圾是指JVM中没有任何引用指向它的对象,如果不及时清理这些垃圾对象,那么它就会一直占用内存,如果垃圾对象越来越多,就会出现OOM了。要判断对象是否是垃圾对象有两种方式,一、引用计数法。二、可达性分析法。而要清除垃圾对象有三种常用方式,一、标记-清除算......
  • 7.《双指针篇》---⑦三数之和(中等偏难)
    题目传送门 方法一:双指针1.新建一个顺序表用来返回结果。并排序数组。2.for循环i从第一个数组元素遍历到倒数第三个数。3.如果遍历过程中有值大于0的则break; 4.定义左右指针,以及target。intleft=i+1,right=n-1;inttarget=-nums[i];5.类似两数之和。......
  • 关于我、重生到500年前凭借C语言改变世界科技vlog.15——深入理解指针(4)
    文章目录1.回调函数的介绍2.qsort使用实例2.1qsort函数介绍2.2使用qsort函数排序整型数据2.3使用qsort排序结构数据3.qsort的模拟实现希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力!1.回调函数的介绍回调函数就是一个通过函数指针调用的......
  • 【C/C++】野指针概念以及避免方式
    C语言中的野指针详解野指针(WildPointer)是指向未定义或非法内存位置的指针。本博客讲解野指针的概念、产生原因、危害以及如何避免野指针的问题。1.什么是野指针野指针指的是未初始化或已经失效的指针变量。这些指针指向的内存位置不再有效,可能被系统回收或被其他变量使......
  • 深入理解 JVM 虚拟机之 CPU 飙高的排查方案及思路(JVM 虚拟机篇 - 19)
    目录《深入理解JVM虚拟机之CPU飙高的排查方案及思路(JVM虚拟机篇-19)》什么是CPU飙高问题?CPU飙高的排查思路在Java应用程序的运行过程中,CPU使用率异常飙高是一个需要关注的问题,这可能严重影响系统的性能和稳定性。对于JVM(Java虚拟机)而言,了解如何排查CPU飙......
  • 在 Windows 中,diantz 工具可用于将现有的文件打包为 CAB 文件,类似于 makecab 命令。di
    diantz|MicrosoftLearn.cab文件(Cabinet文件)是一种压缩文件格式,用于存储多个文件或文件夹。它通常用于Windows操作系统中,作为安装包的一部分,尤其是在驱动程序、应用程序和系统文件的分发中。.cab文件通过压缩算法(如LZX或MSZIP)减小文件体积,便于存储和传输。它可以包......