对象引用有多大?

22

请问在Android的Java虚拟机中,一个引用所占用的大小是多少?

更多信息:

我的意思是,如果我们有

String str = "Watever";

我需要的是str所取得的内容,而不是"Watever"。-- "Watever"是指针(或引用)所指向的位置中保存的内容,而这个指针(或引用)是由str所持有的。

另外,如果我们有

String str = null;

它消耗多少内存?和其他str一样吗?

现在,如果我们有:

Object obj[] = new object[2];

obj消耗多少,obj[1]obj[2]各自消耗多少?


问题的原因如下:(以防有人能推荐一些东西)。
我正在开发一个管理从互联网下载的许多图片的应用程序。我开始将这些图片存储在一个“库”中(由图片列表组成)。
当在图库中显示这些图片时,我过去会在列表中搜索图片(速度慢),如果图片不在那里,我就会显示一个临时下载图像,直到图片被下载完毕。
由于这发生在UI线程上,应用程序变得非常缓慢,所以我考虑在银行中实现哈希表,而不是我拥有的列表。
正如我之前解释的那样,这个搜索发生在UI线程上(我无法改变这一点)。因此,如果碰撞开始减慢线程,碰撞可能会成为一个问题。
我已经读到,“为了平衡时间和空间效率,哈希表应该占用约一半的空间”,但这会使碰撞发生一半的时间(对UI线程来说不实用)。这让我想到要有一个非常长的哈希表(与保存的图片数量相比),并使用更多的RAM(VMHeap空闲较少)。
在确定哈希表的大小之前,我想知道它将消耗多少内存,以免夸大其词。
我知道哈希表的大小可能非常小,与图片可能消耗的内存相比,但我想确保我不会消耗比必要更多的内存。

在提出这个问题之前,我在其他地方进行了搜索,其中包括:

Java中对象引用的大小及其包含的精确信息是什么?

Java中引用类型的大小

哈希教程

(是的,我知道其中两个地方相互矛盾,这也是提问的原因之一)。

2个回答

31
在32位的JVM或Davlik VM上,一个对象或数组引用占据一个32位字(4个字节)。null占用与引用相同的空间。(这是必须的,因为null必须适合于引用类型的插槽中;即实例字段、局部变量等)
另一方面,一个对象占据至少2个32位字(8字节),一个数组占据至少3个32位字(12字节)。实际大小取决于对象的字段数和种类以及数组的元素数量和种类。
对于64位JVM,引用的大小为64位,除非已配置JVM使用压缩指针:
-XX:+UseCompressedOops 启用压缩指针(对象引用表示为32位偏移量而不是64位指针),以获得小于32GB的Java堆大小的优化64位性能。
这是你问题的重点。
在确定哈希表的大小之前,我想知道它将占用多少内存,以免夸大其词。
如果你分配了一个具有大型初始大小的HashMapHashtable,那么大部分空间将被哈希数组占用。这是一个引用数组,因此大小将为3 + initialSize 32位字。这不太可能是重要的…除非你的大小估计非常错误。
但是,我认为你可能过分担心性能。如果你在默认分配的HashMapHashtable中存储对象,则类将随着它变得更大而自动调整哈希表的大小。因此,只要你的对象具有良好的哈希函数(不太慢,不会将所有内容哈希到少量值),哈希表就不应该成为直接的CPU性能问题。

1
不会。数组头需要3个单词,每个元素需要1个单词;即总共5个单词。(该数组保存的是对象的引用而非实际对象。) - Stephen C
通用对象呢?它们也使用三个单词吗? - HopefullyHelpful
好的,我认为通用对象也只使用了两个单词,因为存在类型擦除。 - HopefullyHelpful
通用对象与非泛型对象具有完全相同的运行时表示方式...包括对象头的大小。 - Stephen C
通常,泛型和非泛型对象都有两个单词的标题。区别在于非数组对象不需要具有“长度”字段。 - Stephen C
显示剩余2条评论

5

参考文献几乎是免费的。与图像相比,更是如此。

在 Map 中有一些冲突并不是真正的问题。解决冲突比线性搜索列表中的项目要快得多。话虽如此,通过对排序后的项目进行二进制搜索是保持内存使用率低的好方法(与 Map 相比)。

我可以证明,对于地图来说,初始大小越小越有效 - 我最近编写了一个程序,用于制作 170000 个英语单词的 Trie 结构。当我将初始大小设置为 26 时,到达以 R 开头的单词时,我的内存就会耗尽。将其缩小到 5,我能够创建地图而不会出现内存问题,并且可以在极短的时间内搜索树(带有许多冲突)。

[编辑] 如果引用是 32 位(4 字节),您的平均图像约为 2 兆字节,则可以将 500000 个引用放入与单个图像相同的空间中。您不必担心引用。


非常感谢。我选择给Stephen C答案,因为他回答了确切的问题,但我会给你一个+1,因为你确认了我的想法,并给了我一个关于哈希表的好例子(我从未创建过)。我认为这个问题对我同样有帮助。 - J-Rou
另外,我的平均图像大小为60k,因此可以容纳约7500个32位的引用。这已经足够了。 - J-Rou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接