1

From this Number of String Objects on stack overflow,I came to know that if we do some thing like :

String s = new String("ABC");

Then we have two objects one on heap that is String and one on constant pool that is "ABC",

But today I took the heap dump and found there are two objects on heap it self. I used MAT tool for the same please find the screen shot below.

enter image description here

So my query is if there are two Objects on heap one of Char[] and other for String class and one on constant pool then thus this means that

String s = new String("ABC") will create 3 objects in total.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
T-Bag
  • 10,916
  • 3
  • 54
  • 118
  • 1
    Given your comments, I suggest you edit the Question to express your particular concerns or interest. Examining the internals of such a class as String is generally not a worthwhile endeavor, as such internals are in a sense "none of our business" in object-oriented programming. Indeed, the implementation and handling of the **String class has changed** significantly in Java 9. – Basil Bourque Sep 25 '17 at 15:22

4 Answers4

7

There seems to be repeated nonsense about string literals and the string pool all over the internet. Just to to emphasize, how heap in defined:

The Java® Virtual Machine Specification

2.5.3. Heap

The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.

So, regardless of how a virtual machine implements it, all objects are living in the heap, as that’s how the term heap is defined. The heap is the memory, all object instances are allocated from, hence, all objects are allocated from the heap. In the past, objects for string literals and objects created via new used to live in different memory regions, but still, all of those were part of the heap.

In recent JVMs, all String instances are created in the same memory region, whether created for a literal or for an instance created via new.

In either case, the string pool to manage string literals and “interned” strings is a table of references to these strings. The table itself may live outside the heap, the objects do not.

In your example, you have two String instances and one char[] array, because Strings are implemented as wrappers around char[] arrays and both strings share the array. But that’s an implementation detail. In other (older) JVMs, that array got copied when you construct one string from another using the String(String) constructor. So in these JVMs, your example would create two String instances and two char[] array instances.

Even more fancy, with up to date JVMs and an appropriate configuration, the JVM will identify String instances with different arrays but identical content and change them to share an array to reduce the memory consumption. This feature is called String Deduplication. On Stack Overflow, see: String Deduplication feature of Java 8.

Community
  • 1
  • 1
Holger
  • 285,553
  • 42
  • 434
  • 765
5

The char[] is an internal field of String (after all, it has to store the characters somewhere).

Internal fields are not counted when asking "how many objects are created".

If asked how many objects are created by this:

Map<Integer, Integer> map = new HashMap<>();

the consensus would be "1". Internally, many objects are created (I haven't analyzed it, but my guess would be more than 20), but implementation choices are not part of the question.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • @Bohemian- Thanks, but on the basis of data that I shared are you agree that there will be total of 3 objects in Memory. – T-Bag Sep 25 '17 at 14:19
  • 3
    @LoneWolf If you counted *every* object, there would be many more than that. That's not the intention of "How many objects are created" type questions. – Bohemian Sep 25 '17 at 14:24
  • 3
    Given the current implementation, a freshly constructed `HashMap` truly consists of that `HashMap` instance and nothing else. All other artifacts are populated lazily. And even when putting something into it, the footprint is by far not that expensive. Putting the first entry causes the allocation of one array (initially all-`null`) and one `Entry` instance. Still makes only three objects total. For every subsequent `put`, exactly one additional `Entry` instance will be created. Well, and guessing about the intention of “*How many objects are created*” type questions leads to nowhere… – Holger Sep 25 '17 at 17:23
  • 1
    @Holger I found this an interesting statement and measured with `jol` an empty `Map map = new HashMap<>();` and it seems it weights 48 bytes - indeed no objects (but a few primitives like `size`, `modCount`, etc). – Eugene Sep 25 '17 at 19:16
  • 1
    @Holger but as soon as I add a single entry, the size grows to 176 bytes... indeed there is an array of `Node`s (`Entry`), `Key` and `Value`, `Node` and `HashMap` itself - more like 5 – Eugene Sep 25 '17 at 19:49
  • 1
    @Eugene: well, an array may have quite a large size, up to gigabytes, yet is only one array. The key and value do not count, as they must exist *before* you can call `put` with them as argument and may still be used outside the map. Makes the already mentioned three objects, the `HashMap` itself, the array (default capacity of `16`) and the Entry (aka Node). You can raise the memory consumption by calling `keySet()`, `entrySet()` and `values()`, as these views are remembered for reuse. – Holger Sep 26 '17 at 06:53
0

Every Java String object has a private final char value[]; representing the String's immutable contents (see source).

This seems to reflect what you are seeing in your heap analysis.

Mena
  • 47,782
  • 11
  • 87
  • 106
  • Yes, I know but question is if char[] is also an object so what is total number of objects ? – T-Bag Sep 25 '17 at 14:14
  • 1
    @LoneWolf "question is if char[] is also an object" all arrays are objects in Java. – Pshemo Sep 25 '17 at 14:16
  • 1
    @LoneWolf Yes, original string literal "ABC" and array which holds letters `A` `B` and `C` and other string which you created via `new String(...)` which copies reference to same char array. So this code has 2 string objects with 1 common char array. – Pshemo Sep 25 '17 at 14:21
0

It's representation of inner field char[]value nothing about pool. And new String constructor makes a duplicate of original, which is string already

AlexGera
  • 756
  • 9
  • 19