java对象的指针压缩

版权声明:本文为CSDN博主「ignorewho」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ignorewho/article/details/80840290

什么是java对象的指针压缩?

 1.jdk1.6 update14开始,在64bit操作系统中,JVM支持指针压缩

 2.jvm配置参数:UseCompressedOops,compressed--压缩、oop--对象指针

 3.启用指针压缩:-XX:+UseCompressedOops,禁止指针压缩:-XX:-UseCompressedOops

 


 为什么要进行指针压缩?

 1.在64位平台的HotSpot中使用32位指针,内存使用会多出1.5倍左右,使用较大指针在主内存和缓存之间移动数据,占用较大宽带,同时GC也会承受较大压力

 2.为了减少64位平台下内存的消耗,启用指针压缩功能

 3.在jvm中,32位地址表示4G个对象的指针,在4G-32G堆内存范围内,可以通过编码、解码方式进行优化,使得jvm可以支持更大的内存配置

 4.堆内存小于4G时,不需要启用指针压缩,jvm会直接去除高32位地址,即使用低虚拟地址空间

 5.堆内存大于32G时,压缩指针会失效,会强制使用64位(即8字节)来对java对象寻址,这就会出现1的问题,所以堆内存不要大于32G为好

 


 指针压缩的原理是什么?

 1.解释器解释字节码,植入压缩指令,进行编码、解码

 2.需要操作系统底层支持:GC堆从虚拟地址0开始分配

 


 哪些信息会被压缩?

 1.对象的全局静态变量(即类属性)

 2.对象头信息:64位平台下,原生对象头大小为16字节,压缩后为12字节

 3.对象的引用类型:64位平台下,引用类型本身大小为8字节,压缩后为4字节

 4.对象数组类型:64位平台下,数组类型本身大小为24字节,压缩后16字节

 


 哪些信息不会被压缩?

 1.指向非Heap的对象指针

 2.局部变量、传参、返回值、NULL指针

 


 实际演练:

 基于上一节:
 JAVA-如何计算一个对象的大小

 测试代码做简单修改:
/**
 * @author ignore1992
 *
 * 2018-6-26
 */
public class Main
{
public static void main(String[] args)
{
//1.测试包含非基本类型属性的对象大小
System.out.println(String.format("sizeof(new A):%s", ObjectSizeService.sizeOf(new A())));
//2.测试包含非基本类型属性的对象大小
System.out.println(String.format("sizeof(new B):%s", ObjectSizeService.sizeOf(new B())));
//3.测试基本类型数组对象的大小
System.out.println(String.format("sizeof(new int[0]):%s", ObjectSizeService.sizeOf(new int[0])));
System.out.println(String.format("sizeof(new int[1]):%s", ObjectSizeService.sizeOf(new int[1])));
//4.测试非基本类型数组对象的大小
System.out.println(String.format("sizeof(new A[0]):%s", ObjectSizeService.sizeOf(new A[0])));
System.out.println(String.format("sizeof(new A[1]):%s", ObjectSizeService.sizeOf(new A[1])));
}
}
class A
{
    //基本类型
    int a = 0;
}
class B
{
    //引用类型
    Integer b = 0;
}

 不启用指针压缩,执行:

 java -javaagent:java-objectsize-0.0.1-SNAPSHOT.jar -XX:-UseCompressedOops -jar java-objectsize-0.0.1-SNAPSHOT.jar

 日志打印如下:

 sizeof(new A):24

 sizeof(new B):24

 sizeof(new int[0]):24

 sizeof(new int[1]):32

 


 启用指针压缩,执行:

 java -javaagent:java-objectsize-0.0.1-SNAPSHOT.jar -XX:+UseCompressedOops -jar java-objectsize-0.0.1-SNAPSHOT.jar

 日志打印如下:

 sizeof(new A):16

 sizeof(new B):16

 sizeof(new int[0]):16

 sizeof(new int[1]):24

 


 可以根据上面打印的日志以及前面提到的指针压缩做简要的分析:

 1.未开启指针压缩:

 sizeof(new A):24 ---对象头(16字节)+实例数据(基本类型4字节)+对齐填充(4字节)

 sizeof(new B):24 ---对象头(16字节)+实例数据(引用类型8字节)+对齐填充(0字节)

 sizeof(new int[0]):24 ---对象头(24字节)+实例数据(0字节)+对齐填充(0字节)

 sizeof(new int[1]):32 ---对象头(24字节)+实例数据(基本类型4字节)+对齐填充(4字节)

 


 2.开启指针压缩:

 sizeof(new A):16 ---对象头(压缩后12字节)+实例数据(基本类型4字节)+对齐填充(0字节)

 sizeof(new B):16 ---对象头(压缩后12字节)+实例数据(压缩后引用类型4字节)+对齐填充(0字节)

 sizeof(new int[0]):16 ---对象头(压缩后16字节)+实例数据(0字节)+对齐填充(0字节)

 sizeof(new int[1]):24 ---对象头(压缩后16字节)+实例数据(基本类型4字节)+对齐填充(4字节)

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,可以使用压缩算法对字符串进行压缩以减少其长度。常见的压缩算法包括Gzip、Deflate和Bzip2等。通过对字符串进行压缩,可以减少字符串占用的内存空间,并在网络传输或存储时节省带宽和存储空间。压缩字符串的方法可以是通过统计连续出现的相同字符的次数来实现。首先,定义两个指针i和j,其中i指向字符串的首个字符,j向前遍历直到访问到不同的字符时停止。此时,j - i便是首个字符的连续出现次数。然后,从下个字符开始,重复以上操作,直到遍历完成。最后,将字符以及出现的次数添加到新的字符串对象中。将压缩后的字符串与原始字符串进行比较,返回长度较短的那个。在Java中,可以使用StringBuilder来创建新的字符串对象,使用charAt()方法获取字符串中的字符,通过append()方法将字符和出现次数添加到新的字符串中。最终,通过调用toString()方法将StringBuilder对象转换为字符串。例如: ```java public String compressString(String S) { int i = 0, j = 0, ls = S.length(); StringBuilder res = new StringBuilder(); while (i < ls) { while (j < ls && S.charAt(i) == S.charAt(j)) { j++; } res.append(S.charAt(i)).append(j - i); i = j; } return res.length() < ls ? res.toString() : S; } ``` 以上是一个示例代码,可以通过调用compressString()方法来对字符串进行压缩。其中,参数S是待压缩的字符串,返回值是压缩后的字符串。在这个示例中,我们使用Gzip压缩算法对字符串进行压缩,得到压缩后的字节数组。然后,我们输出压缩前后的字符串长度,以便比较压缩效果。最后,我们使用Gzip压缩算法对压缩后的字节数组进行解压缩,得到解压缩后的字符串,并检查解压缩后的字符串是否与原始字符串一致。通过对字符串进行压缩,可以将字符串的长度变短。<span class="em">1</span><span class="em">2</span><span class="em">3</span>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值