In StringJoiner::toString

        final int addLen = prefix.length() + suffix.length();

Looks suspicious. There is no check for overflow here. Looking at the 
constructor it should have raised a OOM much earlier. Will investigate and file 
a bug.

Thanks.

-- Jim


> On Jul 15, 2020, at 1:21 PM, Thomas Schatzl <thomas.scha...@oracle.com> wrote:
> 
> 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

Reply via email to