jvm7 jvm8_我们真的仍然需要32位JVM吗?

jvm7 jvm8

即使在今天(2015年),我们仍然有两个版本或Oracle HotSpot JDK –已调整为32或64位体系结构。 问题是我们是否真的想在服务器甚至笔记本电脑上使用32位JVM? 我们应该有很受欢迎的意见! 如果只需要较小的堆,则使用32位–它具有较小的内存占用空间,因此您的应用程序将使用较少的内存并触发较短的GC暂停。 但这是真的吗? 我将探索三个不同的领域:

  1. 内存占用
  2. GC性能
  3. 整体表现

让我们从内存消耗开始。

内存占用

众所周知,32位和64位JVM之间的主要区别与内存寻址有关。 这意味着所有64位版本的引用都占用8个字节而不是4个字节。幸运的是,JVM附带了压缩对象指针 ,默认情况下,所有小于26GB的堆都启用该对象指针 。 只要32位JVM可以寻址2GB左右(对于目标OS而言,它仍然要少13倍左右),那么这个限制对我们来说是可以接受的。 因此,无需担心对象引用。 唯一不同的对象布局是标记标头,它在64位上大4个字节。 我们还知道Java中的所有对象都是8字节对齐的,因此有两种可能的情况:

  • 最糟糕的是– 64位对象比32位对象大8个字节。 这是因为向标头添加4个字节会导致对象被放入另一个内存插槽,因此我们必须再添加4个字节来填充对齐间隙。
  • 最佳–两个架构上的对象具有相同的大小。 当在32位上有4个字节的对齐间隙时,就会发生这种情况,可以通过其他标记头字节简单地填充它。

现在假设两种不同的应用程序大小来计算这两种情况。 装载了相当大项目的IntelliJ IDEA包含大约700万个对象,这将是我们的较小项目。 对于第二个选项,假设我们有一个大型项目(我称其为“巨大”),其中包含实时集中的5000万个对象。 现在让我们计算最坏的情况:

  • IDEA -> 7 millions * 8 bytes = 53 MB
  • Huge -> 50 millions * 8 bytes = 381 MB

上面的计算向我们显示,在最坏的情况下,IntelliJ会增加大约50MB的堆,而对于某些带有很小对象的大型,高度粒度的项目,实际的应用堆会增加大约50MB。 在第二种情况下,它可能占总堆的25%左右,但对于绝大多数项目而言,它约为2%,几乎没有。

GC性能

这个想法是使用长键将800万个String对象放入Cache中。 一个测试包含4个调用,这意味着有2400万次放入缓存映射。 我使用并行GC,将总堆大小设置为2GB。 结果令人惊讶,因为整个测试很快就在32位JDK上完成了。 3分40秒,而64位虚拟机为4分30秒。 比较GC日志后,我们可以看到,差异主要来自GC暂停:114秒到157秒。 这意味着实际上32位JVM带来的GC开销要低得多– 64位554可以暂停到618。 在下面,您可以查看GC Viewer的屏幕截图(两个轴上的缩放比例均相同)

32位JVM并行GC

32位JVM并行GC

64位JVM并行GC

64位JVM并行GC

我原本希望64位JVM的开销较小,但是基准测试表明,即使总堆使用量在32位上也差不多,我们在Full GC上释放了更多的内存。 年轻一代的停顿时间也相似–两种架构的停顿时间均为0.55秒左右。 但是,平均主要停顿在64位上更高,为3.2,而32位上为2.7。 事实证明,小堆的GC性能在32位JDK上要好得多。 问题是您的应用程序对GC的要求是否很高–在测试中,平均吞吐量约为42-48%。

在更多的“企业”场景中进行了第二次测试。 我们正在从数据库加载实体,并在加载的列表上调用size()方法。 对于大约6分钟的总测试时间,对于64位,我们有133.7s的总暂停时间,对于32位,我们有130.0s的总暂停时间。 堆的使用也非常相似– 64位为730MB,32位JVM为688MB。 这向我们显示,对于正常的“企业”用法,在各种JVM架构上的GC性能之间没有太大差异。

从数据库中选择32位JVM并行GC

从数据库中选择32位JVM并行GC

64位JVM并行GC从数据库中选择

64位JVM并行GC从数据库中选择

即使具有类似的GC性能,32位JVM仍可以在20秒前完成工作(大约5%)。

整体表现

当然,要验证适用于所有应用程序的JVM性能几乎是不可能的,但是我将尝试提供一些有意义的结果。 首先,让我们检查时间性能。

Benchmark                    32bits [ns]   64bits [ns]   ratioSystem.currentTimeMillis()       113.662        22.449    5.08
System.nanoTime()                128.986        20.161    6.40findMaxIntegerInArray           2780.503      2790.969    1.00
findMaxLongInArray              8289.475      3227.029    2.57
countSinForArray                4966.194      3465.188    1.43UUID.randomUUID()               3084.681      2867.699    1.08

正如我们所看到的,与长变量相关的所有操作的最大且绝对明显的区别是。 在64位JVM上,这些操作的速度是2.6到6.3倍之间。 使用整数非常相似,生成随机UUID的速度也快7%左右。 值得一提的是,解释代码(-Xint)具有相似的速度-仅64位版本的JIT效率更高。 那么有什么特别的区别吗? 是! 64位体系结构带有JVM使用的其他处理器寄存器。 检查生成的程序集后,看起来性能提升主要来自使用64位寄存器的可能性,这可以简化长时间的操作。 可以在Wiki页面下找到任何其他更改。 如果要在计算机上运行此程序,则可以在我的GitHub上找到所有基准测试– https://github.com/jkubrynski/benchmarks_arch

结论

在整个IT世界中,我们不能简单地回答-“是的,您应该始终使用** bits JVM”。 这在很大程度上取决于您的应用程序特征。 如我们所见,32位和64位体系结构之间存在许多差异。 即使长期相关操作的JIT性能提高了几百个百分点,我们也可以看到,经过测试的批处理过程在32位JVM上更早完成。 结论–没有简单的答案。 您应该始终检查哪种架构更适合您的要求。

非常感谢Wojtek Kudla审阅本文并执行其他测试:)

翻译自: https://www.javacodegeeks.com/2015/05/do-we-really-still-need-a-32-bit-jvm.html

jvm7 jvm8

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337972.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言中的printf函数,你觉得它简单吗?

点击上方蓝字关注我,了解更多咨询什么是printf函数?printf函数是C语言当中的输出函数,是用来将内容显示在屏幕上的,是C库中的一种函数。printf函数的用法printf函数使用起来很简单,格式:printf(…

tp5怎么生成短链接_请问在tp5中怎样才能使用url函数?

MM们thinkphp中的自动完成函数调用有两种不同的方法,分别为callback与function;12345678910namespace Home\Model;use Think\Model;class UserModel extends Model{protected $_auto array (array(status,1), // 新增的时候把status字段设置为1array(password,md5,…

cuba 平台_CUBA平台的理念

cuba 平台最近发生了很多事。 在CUBA于6月1日正式发布之后,我们推出了新版本,在一些Java网站上发布了我们的第一篇文章,并在伦敦的Devoxx UK会议上介绍了该平台 。 但是在热潮继续之前,大约是时候阐明CUBA背后的哲学了。 与企业软…

C语言进阶:探讨函数指针的的定义与使用

点击上方蓝字关注我,了解更多咨询函数指针今天准备和大家讲解一下我们C语言编程的函数指针,为什么函数也需要指针呢?我是这样理解的函数指针方便我们对函数的调用,当我们需要把一个函数作为参数传给其他参数的时候就必须使用函数指…

jvm gc停顿_在JVM中记录世界停顿

jvm gc停顿不同的事件可能导致JVM暂停所有应用程序线程。 这种暂停称为世界停止(STW)暂停。 触发STW暂停的最常见原因是垃圾回收( 例如github中的示例 ),但是不同的JIT操作( 示例 ),…

-在c语言中什么含义

点击上方蓝字关注我,了解更多咨询->是一个整体,它是用于指向结构体。1.换种说法,如果我们在C语言中定义了一个结构体,然后申明一个指针指向这个结构体,那么我们要用指针取出结构体中的数据,就要用到“-&…

putchar在c语言中怎么用

点击上方蓝字关注我,了解更多咨询putchar在c语言中的作用是向终端输出一个字符,也属于一种C库函数,包含在C标准库中,putchar是一个字符输出,用于快写的时候很方便。首先来看一下c语言的含义,c语言是一门面向…

hibernate查询缓存_Hibernate查询缓存如何工作

hibernate查询缓存介绍 现在,我已经介绍了实体和集合缓存,现在该研究查询缓存的工作原理了。 查询缓存与实体严格相关,它在搜索条件和满足该特定查询过滤器的实体之间绘制关联。 像其他Hibernate功能一样,查询缓存也不像人们想象…

教你快速了解C语言基本结构

点击上方蓝字关注我,了解更多咨询在步入C语言程序世界之前,不要对C语言产生恐惧感,觉得这种语言应该是学者或研究人员的专利。C语言是人类共有的财富,是普通人只要通过努力学习就可以掌握的知识。下面通过一个简单的程序来看一看C…

提高mysql insert速度_让你的insert操作速度增加1000倍的方法

大家平时都会使用insert语句,特别是有时候需要一个大批量的数据来做测试,一条一条insert将会是非常慢的,那么我们如何让我们的inser更快呢。很多时候方法选对了对于我们做事将会是事半功倍。大家平时都会使用insert语句,特别是有时候需要一个大批量的数据来做测试,一条一条inse…

C语言中同名变量,作用域怎么确定?

点击上方蓝字关注我,了解更多咨询C中通常会声明很多变量,变量有不同的作用域。如果出现同名变量,作用域怎么确定?这里先看结论:块中的变量作用域不同,内层块会隐藏外层块中的定义。但离开内层块后&#xff…

C语言基础知识干货收藏

点击上方蓝字关注我,了解更多咨询算法结构:一、顺序结构、选择结构、循环结构;二、循环结构又分为while型、until型、for循环结构;程序流程图;结构化程序设计方法:(1)自顶向下&#…

python xlrd读取文件报错_python中xlrd库如何实现文件读取?

俗话说得好,技多不压身,虽然我们已经掌握了多种可以实现读取文件的方式,但是丝毫不影响我们要学会精益求精,他说学习文件读取的奥秘,况且,数据分析是十分重要的,一切的代码运行,总归…

c语言 %x,%d,%c,%s,%x各代表什么

点击上方蓝字关注我,了解更多咨询转换说明符%a(%A) 浮点数、十六进制数字和p-(P-)记数法(C99)%c 字符%d 有符号十进制整数%f 浮点数(包括float和doulbe)%e(%E) 浮点数指数输出[e-(E-)记数法]%g(%G) 浮点数不显无意义的零”0″%i 有符号十进制整数(与%d相同)%u 无符号…

apache mesos_Apache Mesos + Marathon和Java EE

apache mesosApache Mesos是一个开放源代码群集管理器,可在分布式应用程序或框架之间提供有效的资源隔离和共享。 Apache Mesos从计算机(物理或虚拟)中提取CPU,内存,存储和其他计算资源,从而使容错和弹性的…

C语言表达式用法快来看看

点击上方蓝字关注我,了解更多咨询表达式是C语言的主体。在C语言中,表达式由操作符和操作数组成。最简单的表达式可以只含有一个操作数。根据表达式所含操作符的个数,可以把表达式分为简单表达式和复杂表达式两种,简单表达式是只含…

python导入模块报错_Python 导入上层目录模块报错

背景:当前demo.py 文件,所处目录 D:\py\test\TestCase,需要调用test 目录下的模块,尝试了 新建__init__.py 文件 import test.模块名的方法,无效.报错信息:D:\py\test\TestCase>python demo.pyTraceback…

java int 传引用吗_Java的参数传递是「值传递」还是「引用传递」?

关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题。有人说Java中只有值传递,也有人说值传递和引用传递都是存在的,比较容易让人产生疑问。关于值传递和引用传递其实需要分情况看待。一、Java数据类型我们都知道,Ja…

C语言中变量的存储类别

点击上方蓝字关注我,了解更多咨询在程序中经常会使用到变量,在C程序中可以选择变量的不同存储形式,其存储类别分为静态存储和动态存储。可以通过存储类修饰符来告诉编译器要处理什么样的类型变量,具体主要有自动(auto&…

javafx 项目_JavaFX,Jigsaw项目和JEP 253

javafx 项目因此, Java 9可能会破坏您的代码 …… 如果您的项目使用JavaFX,则这尤其可能,因为许多自定义和自制控件都需要使用内部API。 借助Project Jigsaw,这些内容将无法在Java 9中访问。幸运的是, Oracle在几天前…