问题很简单,Androids Java VM中的引用消耗的大小是多少?
我的意思是:
如果我们有
String str = "Watever";
我需要str
所需的内容,而不是"Watever"
。 - "Watever"
是str
所指向的指针(或引用)指向的位置中保存的内容。
此外,
如果我们有
String str = null;
它消耗了多少内存?它是否与其他str
??
现在,如果我们有:
Object obj[] = new object[2];
obj
消费了多少以及obj[1]
和obj[2]
消耗了多少?
queston的原因如下:(如果有人可以推荐一些东西)。
我正在开发一款能够保存从互联网下载的许多照片的应用。 我开始将这些图片存储在“银行”上(在图片列表中一致)。
当在图库中显示这些图片时,我曾经在列表中搜索图片(SLOW)然后,如果那时图片不存在,我曾经在下载图片之前显示时间下载图像。< / p>
由于这发生在UI线程上,应用程序变得非常慢,所以我考虑在银行上实现哈希表而不是我的列表。
正如我之前解释过的,这种搜索发生在UI线程中(我不能改变它)。因此,如果冲突开始减慢线程,冲突就会成为一个问题。
我已经读过“为了平衡时间和空间效率,哈希表应该是大约半满”,但这使得冲突在一半的时间内发生(对于UI线程不实用)。这让我想到了一个非常长的哈希表(与保存的图片数量相比)并使用更多的RAM(拥有更少的免费VMHeap)。
在确定哈希表的大小之前,我想知道它会消耗多少内存以便不进行扩散。
我知道哈希表的大小与图片可能消耗的内存相比可能非常小,但我想确保我没有消耗更多的内存而不是必需的。
在问这个问题之前,我在其他地方之间搜索
How big is an object reference in Java and precisely what information does it contain?
(是的,我知道其中两个地方相互矛盾,这就是问题的部分原因)。
如果您因任何原因不明白或想了解更多信息,请发表评论,我会尽快回复。
比你多得多。
答案 0 :(得分:26)
对象或数组引用占用32位JVM或Davlik VM上的一个32位字(4个字节)。 null
占用与参考相同的空间。 (必须,因为null必须适合引用类型的槽;即实例字段,局部变量等)。
另一方面,对象占用最少2个32位字(8个字节),并且数组占用最少3个32位字(12个字节)。实际大小取决于对象的字段数量和种类,以及数组的元素数量和种类。
对于64位JVM,引用的大小为64位,除非您已将JVM配置为使用压缩指针:
-XX:+ UseCompressedOops允许使用压缩指针(对象引用表示为32位偏移而不是64位指针),以优化64位性能,Java堆大小小于32gb。
我认为这是你问题的核心。
在确定哈希表的大小之前,我想知道它会消耗多少内存以便不进行扩散。
如果您分配一个初始大小较大的HashMap
或Hashtable
,则大部分空间将被哈希数组占用。这是一个引用数组,因此大小为3 + initialSize
32位字。这不太可能是重要的......除非你的尺寸估计严重错误。
但是,我认为你可能不必要地担心性能问题。如果要将对象存储在默认分配的HashMap
或Hashtable
中,则该类会在哈希表变大时自动调整哈希表的大小。因此,如果您的对象具有合适的散列函数(不是太慢,不会将所有内容散列到少量值),则散列表不应该是直接的CPU性能问题。
答案 1 :(得分:6)
参考资料几乎是免费的。与图像相比更是如此。
在Map中发生一些碰撞并不是一个真正的问题。通过项目列表进行线性搜索可以更快地解决冲突。也就是说,通过排序的项目列表进行二进制搜索将是保持内存使用率下降的好方法(与Map相比)。
我可以保证有一个较小的初始大小的地图的有效性 - 我最近写了一个程序,使Trie结构170000英语单词。当我将初始大小设置为26时,到达R开头的单词时我会耗尽内存。将其缩小到5,我能够创建没有内存问题的地图并且可以搜索树(有很多实际上没有时间碰撞。
[编辑]如果引用是32位(4字节)并且您的平均图像大约为2兆字节,则可以将500000个引用放入与单个图像相同的空间。您不必担心引用。