RFR: JDK-8249258 java/util/StringJoiner/StringJoinerTest.java failed due to OOM (JDK 15)

Thomas Schatzl thomas.schatzl at oracle.com
Wed Jul 15 16:21:34 UTC 2020


Hi,

   I looked a bit at the allocations themselves, but first answering 
questions.

On 15.07.20 15:25, David Holmes wrote:
 > On 15/07/2020 10:18 pm, Jim Laskey wrote:
 >> Thomas explained: That large objects are never moved (outstanding
 >> issue) So, it's possible to fragment the -Xmx4g such that a 2G object
 >> can't be allocated,
 >
 > Naively one would expect that whatever memory was consumed by
 >
 > String maxString = "*".repeat(MAX_ARRAY_LENGTH);
 >
 > in OOM2, would be fully freed and available for use by the same
 > statememt in OOM3. But without knowing the exact allocation patterns

This is true.

Augmenting OOM3 code with allocations/gcs:

Heap has 2.05g (1030 regions)
Allocation 1 for 1025 regions, 2g

   - concurrent mark start pause because of humongous allocation 
attempt; heap has 2.05g
   - not enough free space, so do a young collection, elevate to full 
collection -> heap shrunk to 2M
   - allocation goes through

1)      String maxString = "*".repeat(MAX_ARRAY_LENGTH);
         try {

Allocation 2 for 2048 regions(!), 4g
   - concurrent start pause because of humongous allocation attempt
   - not enough free space, so do a young collection, elevate to full 
collection -> heap stays at 2.05g -> OOME

2)          new StringJoiner(maxString, "", maxString).toString();
             fail("Should have thrown OutOfMemoryError");

Two observations:
- I ask myselves how that test could have ever failed (i.e. not throw an 
OOME). A 4g allocation on a 4g heap can in practice never succeed. This 
is very suspicious.

- It is also interesting why Allocation 2 internally has been truncated 
to a 2048 region allocation. It should be 2049 (4g + 16 bytes header?). 
Checking at lower layers, memory management get a request for 4294967296 
bytes which is exactly 2^32... this is too small for that object. 
Something is truncating that string. Printing it gives a length of 
2147483639 chars (i.e. 2^32-1-9). I assume that is correct to silently 
truncate the result string?

Thanks,
   Thomas


More information about the core-libs-dev mailing list