Java对象大小实例分析


本文小编为大家详细介绍“Java对象大小实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java对象大小实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Java Primitives 的大小是众所周知的,并且从包装盒中提供32 位和 64 位内存字的最小大小分别为 8 和 16 字节。任何较小的长度都按 8 舍入。在计算过程中,我们将考虑这两种情况。由于内存(字节大小)结构的性质,任何内存都是 8 的倍数,如果不是系统会自动添加额外的字节(但 32/64 系统的最小大小仍然是 8 和 16 字节)Java 对象内部没有字段,根据规范,它只有称为header 的元数据。Header 包含两部分:标记词(Mark Word) 和 类指针(class pointer)。在 Java 中,除了基元和引用(最后一个是隐藏的)之外,一切都是对象。所以所有的包装类只是包装相应的原始类型。所以包装器大小一般=对象头对象+内部原始字段大小+内存间隙。所有原始包装器的大小如下表所示:Java数组是非常相似的对象-他们也有不同的原始和对象值。该数组包含headers、数组长度及其单元格(到基元)或对其单元格的引用(对于对象)。为了方便大家清楚明白,我们绘制一个原始整数和大整数(包装器)的数组。因此,你可以看到原始数组和对象数组之间的主要区别——带有引用的附加层。在这个例子中,大多数内存丢失的原因是使用一个整数包装器,它增加了 12 个额外的字节(比原始数据多 3 倍!)。现在我们知道如何计算 Java Object、Java Primitive 和 Java Primitive Wrapper 和 Arrays。Java 中的任何类都不过是一个混合了所有提到的组件的对象:标头(32/64 位操作系统的 8 或 12 字节)。原始(类型字节取决于原始类型)。对象/类/数组(4 字节参考大小)。Java string 它是类的一个很好的例子,所以除了 header 和 hash 之外,它还封装了 char 数组,所以对于长度为 500 的长字符串,我们有:但是我们要考虑到Java String 类有不同的实现,但一般来说,主要大小由char 数组保存。最简单但不可靠的方法是比较内存初始化前后总内存和空闲内存的差异:最好的方法是使用Aleksey Shipilev 编写的Jol 库。这个解决方案会让您惊喜地发现我们可以轻松地调查任何对象/原语/数组。为此,您需要添加下一个 Maven 依赖项:并提供给 ClassLayout.p免费云主机域名arseInstance 你想要估计的任何内容:作为输出,你将看到:纯文本1作为一种选择,怒可以使用分析器(JProfilerVM VisualizerJConsole 等)来观察此结构或其他结构消耗了多少内存。但是这个解决方案是关于分析内存而不是对象结构。在下一段中,我们将使用 JProfiler 来确认我们的计算是正确的。作为一个现实的例子,我们创建类来表示某个数据库表中的数据,其中包含 5 列和 1.000.000 条记录。所以现在我们创建了 100 万用户,对吗?好吧,它在 User 类中的内容并不重要——我们刚刚创建了 1M 个引用。内存使用:1M * 4 字节 = 4000 KB 或 4MB。甚至没有开始,但支付了 4MB。为了确认我们的计算,我们执行我们的代码并将JProfile附加到它。作为替代方案,你可以使用任何其他分析器,例如VisualVM(它是免费的)。。提示:当你分析应用程序时,你可以不时运行 GC 以清理未使用的对象。所以分析的结果:我们有User[]4M 记录的参考点,大小为 4000KB。作为下一步,我们初始化对象并将它们添加到我们的数组中(名称是唯一的 UUID 36 长度大小):现在让我们分析这个应用程序并确认我们的期望。你可能会提到某些值不精确,例如,字符串的大小为 24.224 而不是 24.000,但我们计算了所有字符串,包括内部 JVM 字符串以及与Boolean.FALSE对象相关的相同内容(估计为 16 字节,但在配置文件中,它显然Boolean.TRUE是32,因为也是JVM 内部使用)。对于 1M 记录,我们花费了 212MB,它只有 5 个字段,并且所有字符串长度都受 36 个字符的限制。正如你所看到的,对象非常贪婪。让我们改进 User 对象并用原语替换所有对象(字符串除外)。仅仅通过将字段更改为基元,我们就节省了 56MB(大约 25% 的已用内存)。但我们还通过删除用户和原语之间的额外引用来提高性能。让我们列出一些简单的方法来节省内存消耗:对于 64 位系统,你可以使用压缩的 oop 参数执行 JVM。这是一个相当大的主题,如果设计允许将字段从子类移动到父类,则可能会节省一些内存从前面的例子中,我们看到了原语包装器是如何浪费大量内存的。原始数组不像 Java Collection 接口那样用户友好。但是还有一个替代方案:TroveFastUtilsEclipse Collection 等。让我们比较 来自Trove 库simpleArrayListTDoubleArrayListd内存使用情况。通常,关键区别隐藏在 Double Primitive Wrapper 对象中,而不是 ArrayList TDoubleArrayList 结构中。因此简化 1M 记录的差异:JProfiler 证实了这一点:因此,只需更改集合,我们就可以轻松地将消耗减少 3 倍。读到这里,这篇“Java对象大小实例分析”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注百云主机行业资讯频道。

相关推荐: 如何使用C++实现飞机订票系统

小编给大家分享一下如何使用C++实现飞机订票系统,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体内容如下以上是“如何使用C++实现飞机订票系统”这篇文章的所有内容,感谢各位免费云主…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 09/08 10:33
Next 09/08 10:35

相关推荐