指针和固定大小缓冲区_技术实验室-JVM对象的指针压缩技

jvm是如何针对对象采用压缩技术?

d0ac465c6bc57e92be65106fc774eef9.png

jvm从32位变为64位,内存带宽也增加了一倍,原来32位存储一个变量,现在可以使用64位存储,无形中浪费了大量空间。

下面从我的jvm运行堆参数我们了解下,使用jmap工具,看下详情

$ jmap -heap 21374Attaching to process ID 21374, please wait...Debugger attached successfully.Server compiler detected.JVM version is 25.91-b14 using parallel threads in the new generation. #新生代采用的是并行线程处理方式using thread-local object allocation.Concurrent Mark-Sweep GC #并发标记清除算法#堆配置情况Heap Configuration:#最小堆使用比例,GC后如果发现空闲堆内存占到整个预估堆内存的N%(百分比),则收缩堆内存的预估最大值, 预估堆内存是堆大小动态调控的重要选项之一. 堆内存预估最大值一定小于或等于固定最大值(-Xmx指定的数值). 前者会根据使用情况动态调大或缩小, 以提高GC回收的效率MinHeapFreeRatio = 40#最大对使用比例,GC后如果发现空闲堆内存占到整个预估堆内存的N%(百分比), 则放大堆内存的预估最大值MaxHeapFreeRatio= 70#即-Xmx,最大堆空间大小MaxHeapSize= 536870912 (512.0MB)#新生代预估堆内存占用的默认值NewSize= 201326592 (192.0MB)#新生代预估堆内存占用的默认值MaxNewSize= 201326592 (192.0MB)#年老代的默认大小OldSize= 335544320 (320.0MB)#老年代对比新生代的空间大小, 比如2代表年老代空间是新生代的两倍大小NewRatio= 2#新生代与suvivor的比例,Eden/Survivor的值. 4表示Survivor:Eden=1:4, 因为survivor区有2个, 所以Eden的占比为3/5.Ratio of eden/survivor space size. -XX:SurvivorRatio=6 sets the ratio between each survivor space and eden to be 1:6, each survivor space will be one eighth of the young generation.SurvivorRatio= 4 #元数据区大小,分配给类元数据空间的初始大小(Oracle逻辑存储上的初始高水位,the initial high-water-mark ). 此值为估计值. MetaspaceSize设置得过大会延长垃圾回收时间. 垃圾回收过后, 引起下一次垃圾回收的类元数据空间的大小可能会变大MetaspaceSize=21807104 (20.796875MB) # 类指针压缩空间大小, 默认为1GCompressedClassSpaceSize = 1073741824 (1024.0MB) # 分配给类元数据空间的最大值, 超过此值就会触发Full GC. 此值仅受限于系统内存的大小, JVM会动态地改变此值MaxMetaspaceSize= 268435456 (256.0MB) # G1区块的大小, 取值为1M至32M. 其取值是要根据最小Heap大小划分出2048个区块.G1HeapRegionSize = 0 (0.0MB) Heap Usage:New Generation (Eden + 1 Survivor Space): capacity = 167772160 (160.0MB) used = 143155664 (136.5238800048828MB) free = 24616496 (23.476119995117188MB) 85.32742500305176% usedEden Space: capacity = 134217728 (128.0MB) used = 128747264 (122.782958984375MB) free = 5470464 (5.217041015625MB) 95.92418670654297% usedFrom Space: capacity = 33554432 (32.0MB) used = 14408400 (13.740921020507812MB) free = 19146032 (18.259078979492188MB) 42.940378189086914% usedTo Space: capacity = 33554432 (32.0MB) used = 0 (0.0MB) free = 33554432 (32.0MB) 0.0% usedconcurrent mark-sweep generation: capacity = 335544320 (320.0MB) used = 45371136 (43.269287109375MB) free = 290173184 (276.730712890625MB) 13.521652221679688% used 21404 interned Strings occupying 2163760 bytes.
ca7c4590cbf3f1182194c7090fa048e2.png

重点来了CompressedClassSpaceSize

从jdk1.6 update14开始,在64bit操作系统中,JVM支持指针压缩,jvm配置参数:UseCompressedOops,compressed--压缩、oop--对象指针,启用指针压缩:-XX:+UseCompressedOops,禁止指针压缩:-XX:-UseCompressedOops。

触发条件:

在堆大小在[4G~32G]的时候,这项技术会被触发。

为什么要进行指针压缩?

  • 在64位平台的HotSpot中使用32位指针,内存使用会多出1.5倍左右,使用较大指针在主内存和缓存之间移动数据,占用较大宽带,同时GC也会承受较大压力,为了减少64位平台下内存的消耗,启用指针压缩功能。
  • 在4G-32G堆内存范围内,可以通过编码、解码方式进行优化,使得jvm可以支持更大的内存配置
  • 堆内存小于4G时,不需要启用指针压缩,jvm会直接去除高32位地址,即使用低虚拟地址空间,微服务的拆分也会基于这点考虑,其实启用压缩指针技术也会带来性能损耗。
  • 堆内存大于32G时,压缩指针会失效,会强制使用64位(即8字节)来对java对象寻址,这就会出现1的问题,所以堆内存不要大于32G为好。

指针压缩的原理是什么?

  • 解释器解释字节码,植入压缩指令,进行编码、解码
  • 需要操作系统底层支持:GC堆从虚拟地址0开始分配

哪些信息会被压缩?

  • 对象的全局静态变量(即类属性)
  • 对象头信息:64位平台下,原生对象头大小为16字节,压缩后为12字节
  • 对象的引用类型:64位平台下,引用类型本身大小为8字节,压缩后为4字节
  • 对象数组类型:64位平台下,数组类型本身大小为24字节,压缩后16字节

哪些信息不会被压缩?

  • 指向非Heap的对象指针
  • 局部变量、传参、返回值、NULL指针
d1f04c23d326665adde5d6a71ff8b860.png

小伙伴点击如下链接查看往期资料:

技术实验室-JVM触发GC时机

技术实验室-JVM分代回收

技术实验室-JVM概念模型

技术实验室-JVM详解垃圾收集器

JVM调优精讲-垃圾回收

请喜欢的小伙伴继续关注!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值