How are arrays of java objects used?

We are trying to configure some of the Oracle JVM garbage collection options, and one developer tried using -XX:PretenureSizeThreshold to make sure that a large array of objects was placed in Tenured. I am sure the assumption was that the size of the array is equal to or greater than the total size of all the objects in it.

But in Java, not arrays of objects, but only arrays of links? That is, each object in the array, as well as the array object itself, is separate in memory and is considered as a separate garbage collector? I think that an array object can still be quite large if there are millions of records, but it should not be somewhere near the total size of the objects that it “contains” if each object is much larger than the link.

I think there is confusion because AFAIK, in C:

  • It is possible to have a struct array that really stores struct s.
  • It is also possible to have an array of pointers to struct s.

I'm sure Java always uses 1. for arrays of primitive types and always uses 2. for arrays of objects, and C can use either for any type ...?

What if I use ArrayList with frequent append() (as in this case)? Are only the array copied, not the objects in the array? Also, when the array is copied, even if the old array was in Tenured, the new one starts in Eden, right?

+6
source share
3 answers

But in Java, not arrays of objects, but just arrays of links?

Just links. All objects are allocated on the heap, never on arrays or on the stack (at least officially, the optimizer can use stack allocation, if possible, but it is transparent).

it should not be somewhere near the total size of the objects that it “contains” if each object is much larger than the link.

Yes, in Java, when you say "assign / store an object", you mean a link (pointer in C terminology).

What if I use an ArrayList with frequent append () s (how do we do this)? Is only the array copied, not the objects in the array?

The array receives only copying when resizing is required, that is, very rarely, and the amortized cost is proportional to the number of inserts. Referenced objects are never copied.

Also, when the array is copied, even if the old array was in Tenured, the new one starts in Eden, right?

Yes!

+5
source

But in Java, not arrays of objects, but only arrays of links? That is, each object in the array, as well as the array object itself, is separated in memory and treated as a separate garbage collector?

Yes.

I think there is confusion because AFAIK, in C:

  • It is possible to have an array of structures that really store structures.
  • It is also possible to have an array of pointers to structures.

I'm sure Java always uses 1. for arrays of primitive types and always uses 2. for arrays of objects, and C can use either for any type ...?

Java, like C, usually stores arrays of primitive types as real arrays with elements of these types. Thus, an int[] array with 10 elements usually reserves 10 × 4 bytes for the array, plus the overhead for the entire array object.

Arrays of objects, however, are, as you say, arrays of links. Thus, an object[] of 10 elements will typically occupy 10 × 4 bytes (or perhaps 10 × 8 bytes in 64-bit CPUs) for the array, plus overhead, plus space for each object that refers to each non-zero element , This corresponds to a C array of pointers.

(I use the term “usually” because although, as most JVMs do, they are not required to allocate memory in any special way.)

Also keep in mind that Java does not have true multidimensional arrays like C (or C #). int[][] in Java is actually a one-dimensional array, where each element is a link to its own int[] subframe. In C a int[][] indeed a two-dimensional array of integers (where the lengths of all but the first dimension must be known at compile time).

Adding

Also note that, as you say, C can have true arrays of structures that are neither primitive types nor pointers. Java does not have this feature.

+2
source

Using -XX:PretenureSizeThreshold to configure is unlikely to help you. This parameter applies only to the direct distribution of Eden, while most distributions occur in TLAB (stream local distribution buffer), and -XX:PretenureSizeThreshold ignored.

TLAB can be quite large for a thread that actively allocates memory (several megabytes).

You can adjust the size of the TLAB to reduce this effect, but it is likely to do more harm than good.

+2
source

Source: https://habr.com/ru/post/956108/


All Articles