2

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.

user640121
  • 111
  • 1
  • 1
  • 5
  • this article talks about allocation too http://chaoticjava.com/posts/how-does-garbage-collection-work/ – bluefoot Mar 04 '11 at 19:32

2 Answers2

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.

iluxa
  • 6,941
  • 18
  • 36
  • I understand the array is allocation in contiguous memory. What I am trying to understand that whether address of the first element could be in the young generation area and the address of the last element in the tenured generation. – user640121 Mar 04 '11 at 19:45
  • No, it can't happen. As @iluxa mentioned, if there is not enough contiguous space in YG to fit the whole array, you will get an OOM Error even if the memory stats still shows you that YG is not 100% occupied. – mazaneicha Mar 04 '11 at 20:14
  • To my knowledge: No. Young and tenured are concepts which are applied to objects as a whole, and 'byte[750]' is a single object in this regard. – Lars Mar 04 '11 at 20:19
  • Can you point me to the code which allocates memory for arrays in Java ? I want to make sure that the allocation uses contiguous memory. – euphoria83 Apr 23 '11 at 01:57
0

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.

Hearen
  • 7,420
  • 4
  • 53
  • 63