Java对象占用最少内存的是哪个?

7

这是一个有点傻的问题,但还是要讲一下。

我有一个多线程程序和一个“全局”的唯一元素集合。由于性能原因,我拒绝使用同步Set实现,而选择了ConcurrentHashMap。我不需要Map中的Value部分,所以我想使用Java中内存使用最小的Object。我用另一种方式解决了这个问题(在Map中引用了单个Boolean对象),但我仍然很好奇Java中最小的对象是什么。我一直认为它是Boolean,但我想这不是真的(参见Java - boolean primitive type - sizePrimitive Data Types)。


原始类型与对象不同。Boolean 是不可变的包装对象,而 boolean 是原始类型。 - kosa
1
如果你真的想要一个 Set<K>,你可以使用 Collections.setFromMap(new ConcurrentHashMap<K, Boolean>())。这会为你完成工作 :-) - obataku
如果你真的想要最小的对象,我可能会只使用 Object... 因为它是每个其他 Object 的基类... :-) - obataku
5个回答

5
实际上,并不重要,因为每个关联的值部分都被固定为引用。您甚至可以在这里使用 null 作为值,但是任何其他(固定的)对象引用应该都可以(有时更方便)。我更喜欢使用 Boolean.TRUE(或类似的“众所周知”的单例)。您可以通过以下方式测试成员身份:
if (myMap.get(someKey) != null) { ... }

除了

if (myMap.containsKey(someKey)) { ... }

好的,但是你就不能真正检查键是否存在(除非使用-> KeySet.iterator)。因此需要一个值来执行此检查。否则我有什么遗漏? - alien01
@alien01 Map.keySet().contains() Map.keySet().contains()是Java中用于检查Map对象是否包含指定键的方法。 - obataku
1
@alien 请看编辑。特别是,containsKey 在地图上始终可用。 - Dirk
@Dirk 在使用 myMap.get(someKey) 时,如果没有关联的值(即 get 返回 null),将会在尝试自动拆箱时导致 NullPointerException - obataku

5

如果你想要一个由ConcurrentHashMap支持的Set<K>,你应该使用Collections.newSetFromMap,例如:

final Set<K> set = Collections.newSetFromMap(new ConcurrentHashMap<K, Boolean>());

现在,如果你真的想要重新发明轮子,并且非常在意内存使用,我建议你只是将普通的“Object”用作你的值。由于Java中的每个对象都继承自“Object”(通用基类),因此内存中任何对象的大小都必须大于或等于普通“Object”的大小。你不能使用基本类型,因为泛型类型参数必须是“Object”。
编辑:实际上,分配一个特定的对象来用作你的值将占用比使用预先存在的对象更多的内存,后者很可能会被分配。你可以使用对一个对象的引用,这个对象在VM初始化期间几乎总是会被分配,例如“Object.class”。尽管如此,我仍强烈建议你采用第一种解决方案。

2
一个对象的大小包括:
  • 它所持有的实例变量的大小
  • 一个8或16字节的头文件(取决于Hotspot VM(32/64位))
  • 填充:其大小总是被填充为8字节的倍数。
例如(假设是32位JVM):
public MyBoolObject {
  boolean flag;
}

占用了16字节8字节(头部) + 1字节(实例变量) + 7字节(填充)。
如果您不关心映射值,可以将其设置为null。这会从堆栈(32/64位)中消耗48字节内存。

您还可以查看这个很好的列表,了解着名Java数据结构的成本/元素: http://code.google.com/p/memory-measurer/wiki/ElementCostInDataStructures


0

原始数据类型不是对象。

由于Java中的所有对象都必须继承自超类Object。那么在Java中最小的可想象的对象将是您定义的一个没有成员的类。这样的类将是相当无用的。


0

Object类是可实例化的,它的实例绝对是Java中最小的对象。然而,许多其他对象具有完全相同的内存占用量,在64位虚拟机上,这些对象包括IntegerBoolean。这是由于堆内存对齐所致。


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