7

This is a silly question, but here it goes.

I have a multithreaded program and a "global" Collection of unique elements. I rejected synchronized Set implementations due to performance, for the ConcurrentHashMap. I don't really need the Value part of Map, so I wanted to use the smallest Object in java in terms of memory usage. I solved this issue in a different way (single Boolean object referenced multiple times in the Map), but I am still curious what is the smallest object in Java. I always thought it to be Boolean, but that is not true I think (Java - boolean primitive type - size, Primitive Data Types)

Community
  • 1
  • 1
alien01
  • 1,334
  • 2
  • 14
  • 31
  • Primitive types are different from objects. Boolean is immutable wrapper object, boolean is primitive type. – kosa Aug 26 '12 at 19:04
  • 1
    If you really wanted a `Set`, you can use `Collections.setFromMap(new ConcurrentHashMap())`. This does your work for you :-) – obataku Aug 26 '12 at 19:05
  • If you really wanted the smallest Object, though, I'd probably just use `Object`... since it's the base-class of every other `Object`... :-) – obataku Aug 26 '12 at 19:06

5 Answers5

5

It doesn't really matter, actually, since the value part of each association is fixed to be a reference. You might even use null as value here, but any other (fixed) object reference should be fine (and more convenient sometimes). I'd prefer Boolean.TRUE (or a similar "well known" singleton). You can then test for membership via

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

in addition to

if (myMap.containsKey(someKey)) { ... }
Dirk
  • 30,623
  • 8
  • 82
  • 102
  • Ok, but then you can't really check if key exists (unless -> KeySet.iterator). Thus the need for a value to be able to perform this check. Or am I missing something? – alien01 Aug 26 '12 at 19:09
  • @alien01 `Map.keySet().contains()` – obataku Aug 26 '12 at 19:10
  • 1
    @alien See edit. In particular, `containsKey` is always available on maps. – Dirk Aug 26 '12 at 19:11
  • @Dirk using `myMap.get(someKey)` where there is no associated value (i.e. `get` returns `null`) will cause a `NullPointerException` when trying to auto-unbox. – obataku Aug 26 '12 at 19:11
5

If you want a Set<K> that is backed by a ConcurrentHashMap, you should use Collections.newSetFromMap, e.g.

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

Now, if you really want to reinvent the wheel, and care that much about memory usage, I suggest you merely use a plain Object as your value. Since every object in Java inherits from Object (the universal base class), the size of any object in memory must be greater than or equal to the size of a plain Object. You cannot use a primitives since generic type arguments must be Objects.

EDIT: Actually, allocating a particular object to use as your value here will take more memory than using a preexisting object which will likely be allocated for anyways. You can just use a reference to an object that will more or less always be allocated during VM initialization, e.g. Object.class. I really suggest you just use the first solution, though.

obataku
  • 29,212
  • 3
  • 44
  • 57
2

An object's size consists of:

  • the size of the instance variables it holds
  • an 8 or 16 bytes header (depending on the Hotspot VM (32/64bit))
  • a padding: its size is always padded to be a multiple of 8 bytes.

E.g (assuming a 32bit JVM) :

public MyBoolObject {
  boolean flag;
}

will take up 16 bytes: 8bytes(header) + 1byte(instance variable) + 7bytes(padding).
Since you are not interested in the map values you can set them to null. This consumes 4 or 8 bytes memory from the stack (32/64bit).

You might also check this good list on cost/elements of well-known Java data structures: http://code.google.com/p/memory-measurer/wiki/ElementCostInDataStructures

Lorand Bendig
  • 10,630
  • 1
  • 38
  • 45
0

The primitive data types are not objects.

Since all objects in java must inherit from the super class Object. Then the smallest conceivable object in java would be a class that you define that has no members. Such a class would be pretty useless.

anio
  • 8,903
  • 7
  • 35
  • 53
0

The Object class is instantiable and its instances are definitely the smallest objects in Java. However, many other objects have exactly the same footprint, Integer and Boolean being examples on 64-bit VMs. This is due to heap memory alignment.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436