Large Array allocation across young and tenured po

2019-04-13 14:32发布

问题:

Is it possible for a large array to be allocated across young and tenured areas of java heap?

I think i am simplifying the question a bit given that these areas have their own subregions. I am just trying to understand whether a single allocation can span across multiple regions (young and tenured). If yes then how is garbage collection done, given that the strategy used is different for different regions (I think atleast in case of ParallelGC different collectors are used for different regions).

Here is an example in order to make the question more clear. Lets say -Xms and -Xmx are set at 900M and NewRatio (ratio of young to tenured) is 2. This would lead to a young region of 300M and tenured of 600M. Now if I try to allocated a "new byte[750]" would the allocation go through given that none of the region might have enough contiguous space.

The reason I am asking this question is that I had an issue (OutofMemoryError) with allocating a large array (which was really the majority of allocation in my code) and I resolved it by changing the -XX:NewRatio. My assumption was that the large array will go to tenured region for sure and that my tenured region should at least have as much space as required for the array.

回答1:

Java array are always allocated in contiguous memory. They won't get split up.

New objects are always allocated in young generation, then moved into tenured if they survive enough GC events. So make sure your young allocation is large enough.

If there is no contiguous region of 750 bytes, you won't be able to get new byte[750] to work.



回答2:

iluxa's answer is not quite correct (or perhaps outdated now). If there is no enough space in Young/New generation, a direct allocation in Tenured/Old generation will kick in.

Here is direct quote from [apangin's answer]

That's how the allocation rougly looks like:

  1. Use Thread Local Allocation Buffer (TLAB), if tlab_top + size <= tlab_end
    This is the fastest path. Allocation is just the tlab_top pointer increment.
  2. If TLAB is almost full, create a new TLAB in Eden and retry in a fresh TLAB.
  3. If TLAB remaining space is not enough but is still to big to discard, try to allocate an object directly in Eden. Allocation in Eden is also a pointer increment (eden_top + size <= eden_end) using atomic operation, since Eden is shared between all threads.
  4. If allocation in Eden fails, a minor collection typically occurs.
  5. If there is not enough space in Eden even after Young GC, an attempt to allocate directly in Old generation is made.

And from Peter Lawrey, Larger objects can be placed straight into tenured space.