Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
占用内存最少的Java对象_Java_Performance_Memory_Collections - Fatal编程技术网

占用内存最少的Java对象

占用内存最少的Java对象,java,performance,memory,collections,Java,Performance,Memory,Collections,这是个愚蠢的问题,但问题来了 我有一个多线程程序和一个独特元素的“全局”集合。出于性能原因,我拒绝了ConcurrentHashMap的同步集实现。我真的不需要Map的值部分,所以我想在内存使用方面使用java中最小的对象。我以不同的方式解决了这个问题(单个布尔对象在映射中多次引用),但我仍然很好奇Java中最小的对象是什么。我一直认为它是布尔型的,但事实并非如此,我认为(,)基本数据类型不是对象 因为java中的所有对象都必须从超类对象继承。那么java中最小的对象就是您定义的没有成员的类。这

这是个愚蠢的问题,但问题来了


我有一个多线程程序和一个独特元素的“全局”集合。出于性能原因,我拒绝了ConcurrentHashMap的同步集实现。我真的不需要Map的值部分,所以我想在内存使用方面使用java中最小的对象。我以不同的方式解决了这个问题(单个布尔对象在映射中多次引用),但我仍然很好奇Java中最小的对象是什么。我一直认为它是布尔型的,但事实并非如此,我认为(,)

基本数据类型不是对象


因为java中的所有对象都必须从超类对象继承。那么java中最小的对象就是您定义的没有成员的类。这样一个类是非常无用的。

实际上,这并不重要,因为每个关联的值部分都固定为引用。您甚至可以在这里使用
null
作为值,但是任何其他(固定的)对象引用都可以(有时更方便)。我更喜欢
Boolean.TRUE
(或类似的“知名”单例)。然后,您可以通过

if (myMap.get(someKey) != null) { ... }
除了

if (myMap.containsKey(someKey)) { ... }
如果您想要一个由
ConcurrentHashMap
支持的
集合
,您应该使用,例如

final Set Set=Collections.newSetFromMap(新的ConcurrentHashMap());

现在,如果你真的想重新发明轮子,并且非常关心内存的使用,我建议你只使用一个普通的
对象作为你的值。由于Java中的每个对象都继承自
对象
(通用基类),内存中任何对象的大小都必须大于或等于普通
对象的大小。您不能使用原语,因为泛型类型参数必须是
Object
s


编辑:实际上,在这里分配一个特定的对象作为您的值将比使用一个先前存在的对象占用更多的内存,而这个对象很可能会被分配到任何地方。您可以使用对对象的引用,该对象在VM初始化期间或多或少都会被分配,例如
object.class
。我确实建议您只使用第一种解决方案。

对象
类是可实例化的,它的实例绝对是Java中最小的对象。但是,许多其他对象具有完全相同的占用空间,
Integer
Boolean
是64位虚拟机上的示例。这是由于堆内存对齐。

对象的大小包括:

  • 它所持有的实例变量的大小
  • 8或16字节的标头(取决于热点VM(32/64位))
  • 填充:其大小始终填充为8字节的倍数
例如(假设是32位JVM):

将占用
16字节
8字节
(标题)+
1字节
(实例变量)+
7字节
(填充)。
因为您对映射值不感兴趣,所以可以将它们设置为null。这将消耗堆栈中的
4
8
字节内存(32/64位)

您还可以查看关于众所周知的Java数据结构的成本/要素的良好列表:

基元类型与对象不同。Boolean是不可变的包装器对象,Boolean是基元类型。如果确实需要
集合
,可以使用
集合.setFromMap(新的ConcurrentHashMap())
。这就是你的工作:-)如果你真的想要最小的对象,我可能会使用
对象
。。。因为它是其他所有
对象的基类好的,但您不能真正检查键是否存在(除非->KeySet.iterator)。因此,需要一个值才能执行此检查。还是我遗漏了什么?@alien01
Map.keySet().contains()
@alien请参见编辑。特别是,
containsKey
在地图上始终可用。@Dirk在没有关联值(即
get
返回
null
)的情况下使用
myMap.get(someKey)
,在尝试自动取消装箱时会导致
NullPointerException
final Set<K> set = Collections.newSetFromMap(new ConcurrentHashMap<K, Boolean>());
public MyBoolObject {
  boolean flag;
}