在本文中,我们将向您介绍一种称为Compressed oops的JVM优化。 压缩oop的概念是由32位和64位体系结构之间的差异引起的。 因此,我们将对64位体系结构进行简短的回顾,然后再深入探讨压缩oop的主题。 最后,我们将通过一个简单的示例看到所有这些。

本文的示例代码非常简单,因此我们将不使用任何IDE。 在32位计算机上,压缩oop没有任何意义。 同样,在6u23之前的JDK中,默认情况下未激活它。 因此,我们假设您使用的是比6u23更新的64位JDK。 我们需要的最后一个工具是内存分析器工具。 在此示例中,我们使用了行业标准的Eclipse Memory Analyzer Tool版本1.5。

1. 32位和64位

32位与64位在2000年代初风靡一时。 尽管64位CPU在超级计算机领域并不是什么新鲜事物,但直到最近,个人计算机才将其推向主流。 从32位架构过渡到64位绝非易事,从硬件到操作系统的所有事物都必须改变。 Java通过引入64位虚拟机来拥抱这种转变。

这种过渡的主要优势是存储容量。 在32位系统中,您的内存地址宽度为32位(因此称为名称),这意味着可寻址内存的总量为2 ^ 32或4 GB RAM。 过去,这可能是一台个人计算机的无限内存(毕竟,那些需要超过640kB RAM的内存!),但在拥有1 GB内存的智能手机被认为是低端产品的时候,却不是。 64位体系结构解决了此限制。 在这样的机器中,可寻址内存的理论数量为2 ^ 64,这是一个非常大的数字。 不幸的是,这只是一个理论上的上限,在现实世界中,有很多硬件和软件因素将我们限制在较小的内存上。 例如,Windows 7 Ultimate仅支持最大192GB。 仅将单词用于192 GB似乎有些苛刻,但与2 ^ 64相比,它显得苍白。 现在您已经了解了为什么64位很重要,让我们继续进行下一部分,并了解压缩oop将如何为我们提供帮助。

2.理论上的压缩

“没有免费的午餐之类的东西”。 64位计算机中过多的内存需要付出一定的代价。 通常,一个应用程序在64位系统上会消耗更多的内存,而在非平凡的应用程序中,这个数量是不可忽略的。 压缩的oop通过在64位环境中使用32位类指针来帮助您保留一些内存,前提是您的堆大小不会大于32 GB。 为了更详细地了解这一点,让我们看看如何用Java表示对象。

Java中的对象表示

为了查看Java中对象的表示方式,我们使用一个非常简单的示例,一个持有原始int的Integer对象。 当您编写如下简单的代码行时:

Integer i = new Integer(23);

编译器为此对象分配了超过32位的堆。 在Java中,int的长度为32位,但是每个对象都有标头。 这些标头的大小在32位和64位以及不同的VM中有所不同。 在32位虚拟机中,每个标头字段均为一个字或4个字节。 在64位虚拟机中,保存int的字段保留为32位,但其他字段的大小加倍为8个字节(在64bit环境中为一个字)。 实际上,故事还没有结束。 对象是按字对齐的,这意味着在64位计算机中,它们占用的内存量必须能被64整除。对我们而言,主要关注点是类指针的大小,在Hotspot VM术语中称为Klass。 正如您在下图中所看到的,在64位虚拟机上,klass大小为8个字节,但是启用了压缩oops后,大小变为4个字节。

不同VM中Integer对象的表示形式

压缩的oop如何实现

压缩后的oop中的oop表示普通对象指针。 这些对象指针(如上一节所述)与计算机的本机指针大小相同。 因此,在32位和64位计算机上,oops大小分别为32位或64位。 使用压缩的oop,我们在64位计算机上具有32位指针。

压缩的oop背后的技巧是内存的字节寻址和字寻址之间的区别。 使用字节寻址,您可以访问内存中的每个字节,但每个字节也需要一个唯一的地址。 在32位环境中,这会将您限制为2 ^ 32字节的内存。 在字寻址中,您仍然具有相同数量的可寻址存储块,但是此存储块是一个字而不是一个字节。 在64位计算机中,一个字为8个字节。 这为JVM提供了三个零位。 Java通过转移这些位来利用它们,以扩展可寻址内存并实现压缩的oop。

3.压缩的行动

要查看压缩的操作的效果,我们使用一个简单的应用程序。 这是一个小的Java对象,它制作了200万个整数的链表。

为了能够查看堆条件,我们使用Eclipse Memory Analyzer Tool。 由于我们没有使用Eclipse IDE,因此我们使用独立的应用程序。 您可以从这里下载。

由于此示例仅使用一个类,因此我们不使用Eclipse或任何其他IDE。 使用文本编辑器并创建一个名为IntegerApplication.java的文件。 在文件中键入以下代码。 请记住,文件名应与java类的名称匹配。 您可以从本文的下载部分下载类文件,而无需手动输入。

IntegerApplication.java

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;public class IntegerApplication {public static void main(String[] args) {List<Integer> intList = new LinkedList<>();for(int i=0;i<2000000;i++){Integer number = new Integer(1);intList.add(number);}Scanner scanner = new Scanner(System.in);System.out.println("application is running...");String tmp = scanner.nextLine();System.exit(0);}
}

打开命令提示符窗口,然后导航到该文件的目录。 使用以下命令进行编译。

javac IntegerApplication.java

现在,您应该有一个IntegerApplication.class文件。 我们运行此文件两次,一次启用压缩oop,第二次不使用压缩oop。 在高于6u23的JVM中,默认情况下启用压缩操作,因此您只需要通过在命令提示符下键入以下命令来运行应用程序:

java IntegerApplication

您可能已经注意到源代码中的Scanner对象。 它用于使应用程序保持活动状态,直到您键入某些内容并终止它为止。 如果在命令提示符下看到“应用程序正在运行...”一词,则该启动内存分析器了。 根据您的计算机,它可能需要一段时间才能完成初始化过程。

从文件菜单中选择获取堆转储...

Craft.io选择窗口

您将看到过程选择窗口。 选择名为IntegerApplication的进程,然后单击“完成”。

一段时间后,您将进入MAT的主屏幕。 从工具栏中选择直方图按钮,如图所示:

从工具栏中选择直方图

现在,您可以看到应用程序中所有对象的详细概述。 这是在启用压缩oop的情况下运行的简单应用程序的直方图。

启用压缩oop的应用程序的堆转储。

这次,我们在没有压缩的情况下运行应用程序。 为了禁用压缩的oop,我们使用-XX:-UseCompressedOops标志。 您无需再次重新编译类,只需在命令提示符下键入以下命令:

java -XX:-UseCompressedOops IntegerApplication

同样,当您看到“应用程序正在运行...”文本时,将获得与以前相同的堆转储。 这是应用程序在没有压缩的情况下运行时堆转储的直方图。

禁用压缩oop的应用程序堆转储

正如我们预期的那样,堆大小增加了。 堆的大部分被两种类型的对象占据,即链表节点和整数。 在压缩oop版本中,有超过200万个整数需要3200万个字节,而在非压缩oop版本中则需要4800万个字节。 通过简单的数学运算,我们可以看到这完全符合我们的预测。

2000000 *(128/8)= 32000000或32兆字节

2000000 *(192/8)= 48000000或48兆字节

如果您在第二个方程式中注意到我们使用了192,而在上一节中,对象大小被称为160位。 原因是Java是按字节寻址的,因此地址与最接近的8个字节对齐(在这种情况下为192位)。

4。结论

这里提供的示例是人为设计的,但这并不意味着它在现实世界的应用程序中不成立。 与H2数据库应用程序一起测试时,压缩的oop将堆大小从3.6兆字节减少到了3.1兆字节。 这将宝贵堆空间的使用效率提高了近14%。 如我们所见,使用压缩的oop并没有什么危害,实际上,大多数情况下,您不会禁用此功能。 但是,了解编译器技巧的细节可以帮助编写考虑性能的代码。

下载源代码

这是看到压缩的oops效果起作用的示例。

下载
您可以在此处下载此示例中使用的IntegerApplication类的完整代码: IntegerApplication

翻译自: https://www.javacodegeeks.com/2016/05/compressedoops-introduction-compressed-references-java.html

CompressedOops:Java压缩参考简介相关推荐

  1. java开发工具包 jdk_什么是JDK? Java开发工具包简介

    java开发工具包 jdk Java开发工具包(JDK)与JVM(Java虚拟机)和JRE(Java运行时环境)一起是Java编程中使用的三个核心技术软件包之一. 重要的是要区分这三种技术,并了解它们 ...

  2. java如何压缩html代码,java 压缩html文件

    java 压缩html文件 [2021-02-03 16:32:07]  简介: php去除nbsp的方法:首先创建一个PHP代码示例文件:然后通过"preg_replace("/ ...

  3. java.util.concurrent简介

    文章目录 主要的组件 Executor ExecutorService ScheduledExecutorService Future CountDownLatch CyclicBarrier Sem ...

  4. java 模块化osgi_OSGi简介–模块化Java

    java 模块化osgi OSGi联盟是这种搁浅的管理机构,它始于1999年.其最初目标是为网络设备创建开放搁浅. 基于此思想,此规范也针对Java引入. Eclipse在Java中是第一个. 他们于 ...

  5. java压缩_Java压缩

    java压缩 在最近的项目中,我们不得不做一些我个人从未真正看过的事情. 压缩. 我们需要拍摄几个文件和图像,将它们压缩并提供给FTP使用,是的,总有一天,感觉确实回到了90年代. 除了过去的FTP之 ...

  6. java开源工具简介(2)

    java开源工具简介(2) OpenCms [Java开源 CMS系统] OpenCms是一个J2EE的产品,它是用Java写成的.它和Tomcat捆绑在一起.但是也能够使用ATG Dynamo.We ...

  7. 双表查询java代码_什么是JDBC?Java数据库连接性简介

    JDBC(Java数据库连接性)是Java API,用于管理与数据库的连接,发出查询和命令以及处理从数据库获得的结果集.JDBC在1997年作为JDK 1.1的一部分发布,是为Java持久层开发的首批 ...

  8. Java面试参考指南(二)

    2019独角兽企业重金招聘Python工程师标准>>> 访问修饰符 对于基本的OOPS(面向对象)概念,请看Java面试参考指南的第一部分.访问修饰符规定了一个类如何访问另一个类及它 ...

  9. java 压缩技术_Java压缩技术(三) ZIP解压缩——Java原生实现

    JavaEye的朋友跟我说:"你一口气把ZIP压缩和解压缩都写到一个帖子里,我看起来很累,不如分开好阅读".ok,面向读者需求,我做调整,这里单说ZIP解压缩! 相关链接: Jav ...

最新文章

  1. Java 反射 方法调用
  2. 破解中国电信华为无线猫路由(HG522-C)自己主动拨号+不限电脑数+iTV
  3. HTML5和Flash——如何选择合适的工具
  4. HDU2819Swap(二分图最大匹配)
  5. window的onresize执行多次的解决方法
  6. 刷OJ时输入输出与字符串
  7. 推荐搜索炼丹笔记:MiNet阿里跨域点击率CTR预估
  8. 使用SAP WebIDE往Github上推送代码修改时遇到错误消息 Commit request failed Commit failed. Ref must be HEAD and is HEAD
  9. 别求面经了!小夕手把手教你如何斩下和选择NLP算法岗offer!(2020.4.14更新)...
  10. sql左外连接和右外连接的区别
  11. mysql半连接_MySQL优化案例:半连接(semi join)优化方式导致的查询性能低下(转载)...
  12. Ubuntu 18.04LTS系统设置窗口打不开或者消失解决办法
  13. 不再支持Postman集合v1格式,无法直接导入
  14. 闭包基础概念,闭包详解
  15. Linux静态库运行找不到lc,创建和使用静态库(问题:undefined reference)
  16. YALMIP学习总结
  17. 如何在YouTube上制作播放列表
  18. 怎么看rx580是不是470刷的_AMD RX470/570强刷RX580完整图文教程(附文件下载及查BIOS攻略)...
  19. python(十)——文件读写、OS模块、win32控制窗体、语音合成
  20. 利用Crimestat(犯罪统计)软件进行空间分析

热门文章

  1. JAVA反射修改常量,以及其局限
  2. 最全三大框架整合(使用映射)——applicationContext.xml里面的配置
  3. 并查集判断是否有环存在
  4. 2015蓝桥杯省赛---java---B---6(加法变乘法)
  5. MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established
  6. php批量评价,彻底杜绝 WordPress 批量垃圾评论留言的三步曲
  7. qq空间说说服务器维护,如何解决QQ空间说说发表不了
  8. mysql事务基础+基于innodb的行锁+间隙锁+如何锁定行
  9. java泛型程序设计——Varargs 警告+不能实例化类型变量
  10. SpringMVC控制器方法获取参数时@RequestParam注解加与不加的区别