这是一个愚蠢的问题,但它就在这里。
我有一个多线程程序和一个独特元素的“全局”集合。由于性能,我拒绝了 ConcurrentHashMap 的同步 Set 实现。我真的不需要 Map 的 Value 部分,所以我想在内存使用方面使用 java 中最小的 Object。我以不同的方式解决了这个问题(在 Map 中多次引用单个布尔对象),但我仍然很好奇 Java 中最小的对象是什么。我一直认为它是布尔值,但我认为这不是真的(Java-布尔原始类型-大小,原始数据类型)
这是一个愚蠢的问题,但它就在这里。
我有一个多线程程序和一个独特元素的“全局”集合。由于性能,我拒绝了 ConcurrentHashMap 的同步 Set 实现。我真的不需要 Map 的 Value 部分,所以我想在内存使用方面使用 java 中最小的 Object。我以不同的方式解决了这个问题(在 Map 中多次引用单个布尔对象),但我仍然很好奇 Java 中最小的对象是什么。我一直认为它是布尔值,但我认为这不是真的(Java-布尔原始类型-大小,原始数据类型)
实际上,这并不重要,因为每个关联的值部分都固定为参考。您甚至可以null
在这里使用 as value,但任何其他(固定)对象引用都应该没问题(有时更方便)。我更喜欢Boolean.TRUE
(或类似的“众所周知的”单身人士)。然后,您可以通过以下方式测试会员资格
if (myMap.get(someKey) != null) { ... }
此外
if (myMap.containsKey(someKey)) { ... }
如果你想要一个Set<K>
由 a 支持的 a ConcurrentHashMap
,你应该使用Collections.newSetFromMap
,例如
final Set<K> set = Collections.newSetFromMap(new ConcurrentHashMap<K, Boolean>());
现在,如果你真的想重新发明轮子,并且非常关心内存使用情况,我建议你只使用一个 plainObject
作为你的值。由于 Java 中的每个对象都继承自Object
(通用基类),因此内存中任何对象的大小都必须大于或等于 plain 的大小Object
。您不能使用原语,因为泛型类型参数必须是Object
s。
编辑:实际上,在这里分配一个特定对象用作您的值将比使用可能分配给任何情况的预先存在的对象占用更多的内存。您可以只使用对在 VM 初始化期间或多或少总是分配的对象的引用,例如Object.class
. 不过,我真的建议您只使用第一个解决方案。
对象的大小包括:
例如(假设 32 位 JVM):
public MyBoolObject {
boolean flag;
}
将占用16 bytes
:(8bytes
标题)+ 1byte
(实例变量)+ 7bytes
(填充)。
由于您对地图值不感兴趣,因此可以将它们设置为 null。这会消耗4
或占用8
堆栈中的内存(32/64 位)。
您还可以查看这个关于众所周知的 Java 数据结构的成本/元素的好列表: http ://code.google.com/p/memory-measurer/wiki/ElementCostInDataStructures
原始数据类型不是对象。
由于java中的所有对象都必须继承自超类Object。那么Java中最小的可以想象的对象将是您定义的没有成员的类。这样的课程将毫无用处。
该类Object
是可实例化的,它的实例绝对是 Java 中最小的对象。但是,许多其他对象具有完全相同的占用空间,Integer
并且Boolean
是 64 位 VM 上的示例。这是由于堆内存对齐。