Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the profiler show large numbers of char[] instances when I am not creating any?

Tags:

java

profiling

I am running a NetBeans profile of a recursive operation that includes creating a class with a java.lang.String field. In the classes list, in the profile heap dump, the number of String fields corresponds to the number of classes created as expected, however there are also a similar number of char[] instances. The char arrays account for nearly 70% of the memory usage(!) whilst the String field accounts for about 7%.

What is going on here? And how can I reduce the number of char[] instances?

Thanks

like image 416
MalcomTucker Avatar asked Dec 31 '09 13:12

MalcomTucker


4 Answers

Take a look at the String source code. The String object itself contains a cached hash code, a count of the number of characters (again, for optimisation purposes), an offset (since a String.substr() points to the original string data) and the character array, which contains the actual string data. Hence your metrics showing that String consumes relatively little, but the majority of memory is taken by the underlying character arrays.

like image 123
Brian Agnew Avatar answered Oct 31 '22 18:10

Brian Agnew


The char arrays account for nearly 70% of the memory usage(!) whilst the String field accounts for about 7%

This is subtlety of memory profiling known as "retained size" and "shallow size":

  • Shallow size refers to how much memory is taken up by an object, not including any child objects it contains. Basically, this means primitive fields.
  • Retained size is the shallow size plus the size of the other objects referred to by the object, but only those other objects which are referred to only by this object (tricky to explain, simple concept).

String is the perfect example. It contains a handful of primitive fields, plus the char[]. The char[] accounts for the vast majority of the memory usage. The shallow size of String is very small, but it's retained size is much larger, since that includes the char[].

The NetBeans profiler is probably giving you the shallow size, which isn't a very useful figure, but is easy to calculate. The retained size would incorporate the char[] memory usage into the String memory usage, but calculating the retained size is computationally expensive, and so profilers won't work that out until explicitly asked to.

like image 30
skaffman Avatar answered Oct 31 '22 16:10

skaffman


The String class in the Sun's Java implementation uses a char[] to store the character data.

I believe this can be verified without looking at the source code by using a debugger to look at the contents of a String, or by using reflection to look at the internals of the String object.

Therefore, it would be difficult to reduce the number of char[] which are being created, unless the number of String instances which are being created were reduced.

like image 2
coobird Avatar answered Oct 31 '22 17:10

coobird


Strings are backed by char arrays, so I don't think you can reduce the number of char[] instances without reducing your Strings.

Have you tried removing some Strings to see if the char[]s go down as well?

like image 1
Jack Leow Avatar answered Oct 31 '22 18:10

Jack Leow