About the location of data structure and its inner objects

Lijie Xu csxulijie at gmail.com
Thu Aug 29 01:53:31 UTC 2013


Thanks for all the professional answers. I think I need more practice to
understand those GC algorithms better.


On Thu, Aug 29, 2013 at 1:47 AM, Jon Masamitsu <jon.masamitsu at oracle.com>wrote:

>
> On 8/28/2013 1:42 AM, Krystal Mok wrote:
>
>> Hi Lijie,
>>
>> On Wed, Aug 28, 2013 at 10:46 AM, Lijie Xu <csxulijie at gmail.com> wrote:
>>
>>  Thank Tao, I think I have a graph of memory layout now. I have another
>>> five questions:
>>>
>>> 1) Can old space's max size be adjusted dynamically by GC while the JVM
>>> is
>>> running?
>>>
>>> Yes if you're using UseParallelGC / UseParallelOldGC and
>>>
>> UseAdaptiveSizePolicy is on (it is on by default). Other GCs in HotSpot
>> don't implement adaptive size policy yet.
>>
>
> The maximum size of the heap is fixed at VM initialization.  By default
> the maximum size of the
> old generation is also fixed at initialization.  The exceptions are with
> UseParallelGC and UseG1GC.
>
> With UseParallelGC the GC will move space between the young generation and
> the old
> generation if UseAdaptiveGCBoundary is turned on.  This does not increase
> the maximum
> size of the heap.  There are limits to this movement (i.e., there is a
> minimum size of the
> young generation and a minimum size of the old generation that has to be
> observed).
>
> With UseG1GC the young generation is a logical collection of regions and
> the collection
> changes dynamically.  Again the maximum size of the heap does not increase
> and there
> are limits on the minimum size of the young generation.
>
>
>
>
>>
>>  2) I want to know if FullGC will definitely trigger MinorGC, or just
>>> reclaim the unreferenced objects in Old/Eden/S0/S1 without object
>>> promotion.
>>>
>>> A "full GC" in HotSpot terms collects the whole GC heap, not just the old
>>>
>> generation. It doesn't have to do a separate minor GC before a full GC to
>> collect the young generation.
>> A case for UseParallelGC / UseParallelOldGC is that it defaults to
>> scavenge
>> (do a minor GC) right before a full GC. This behavior can be turned off
>> with -XX:-ScavengeBeforeFullGC
>>
>
> The exception to a "full GC collects the whole heap" is CMS.  A CMS
> mark-sweep  (and a
> concurrent collection is a mark-sweep collection) only collect the old
> generation.
>
> Jon
>
>
>>
>>  3) Whether MinorGC can copy an object directly into Old if the Survior
>>> hasn't enough space to hold it currently?
>>>
>>>  Yes, it could. That would be called a "premature promotion" / "survivor
>> space overflow".
>> It is even possible to directly allocate a new object in the old
>> generation. Assuming you can read Chinese, refer to this thread for an
>> example: http://hllvm.group.iteye.com/**group/topic/38293<http://hllvm.group.iteye.com/group/topic/38293>
>>
>>  4) Can JVM heap use virtual memory or just physical memory?
>>>
>>> In HotSpot VM's case, the virtual address space for the whole GC heap is
>>>
>> allocated up front, during VM intialization, but is then only commited on
>> demand. The virtual memory allocated won't be backed by physical memory
>> before it's commited.
>>
>>
>>  5) Can DirectBuffer use virtual memory or just physical memory?
>>>
>>> A NIO Direct-X-Buffer, if allocated from the Java side, is just a regular
>>>
>> Java object in the Java heap, acting as a proxy to a backing buffer
>> allocated via malloc() on the C heap. Whatever knowledge you have on
>> malloc() applies here.
>> On the other hand, a Direct-X-Buffer can be created via JNI, too, wrapping
>> an existing buffer in native code. [1] You can wrap any piece of native
>> memory into a DirectByteBuffer this way.
>>
>> HTH,
>> Kris
>>
>> [1]:
>> http://docs.oracle.com/javase/**7/docs/technotes/guides/jni/**
>> spec/functions.html#**NewDirectByteBuffer<http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#NewDirectByteBuffer>
>>
>>
>>
>>>
>>> On Tue, Aug 27, 2013 at 2:23 AM, Tao Mao <tao.mao at oracle.com> wrote:
>>>
>>>    Java always conceptually holds a reference rather than the whole
>>>> object
>>>> body, but you can directly see and use the body in C++.
>>>>
>>>> Below let me illustrate on the HashMap example?
>>>>
>>>> Tao
>>>>
>>>>
>>>> On 8/26/13 1:20 AM, Lijie Xu wrote:
>>>>
>>>>   Hi, folks. I’m confused with the concrete locations of the data
>>>> structure and its inner objects in the heap. The questions are below.
>>>>
>>>> A general question:
>>>>
>>>> If an object X is decided to be copied into old from new gen by GC, all
>>>> the objects which can be reached from X are copied into old too. Or X’s
>>>> retained set. Or this statement is wrong.
>>>>
>>>>
>>>>   Two concrete questions.
>>>>
>>>> Q1: Can an array such as byte[], String[] and Object[] span two
>>>> generations?
>>>>
>>>> I think primitive arrays such as byte[] and int[] cannot span (e.g., a
>>>> part of the array exists in eden and the other part exists in old
>>>> space).
>>>> For reference arrays such as Object[], the array itself cannot span but
>>>> the
>>>> items in the arrays can span (i.e., some items exist in new gen while
>>>> others exist in old gen). I’m not sure if I’m right and if String[] is
>>>> as
>>>> same as byte[].
>>>>
>>>>
>>>>
>>>> Q2: Can ArrayList, LinkedList, HashMap span two generations?
>>>>
>>>> For example, I initialize some data structures as follows.
>>>>
>>>> Say, hashMap = {str1: obj1; str2: obj2; ...; strn: objn;}
>>>>
>>>> The object body of hashMap is in the same generation, including the data
>>>> structure containing references of str(i) and obj(i); however, the
>>>> object
>>>> bodies of str(i) and obj(i) may span different generations.
>>>>
>>>> BTW, hashMap itself (not its referenced object body) is a reference and,
>>>> hence, on stack (not on java heap) since it's a local variable.
>>>>
>>>> Hope this helps build a concrete picture of memory layout.
>>>>
>>>>
>>>>
>>>> ------------------------------**------------------------------**
>>>> ------------------------------**--------
>>>>
>>>> *import* java.util.ArrayList;
>>>>
>>>> *import* java.util.HashMap;
>>>>
>>>> *import* java.util.LinkedList;
>>>>
>>>> *import* java.util.List;
>>>>
>>>> *import* java.util.Map;
>>>>
>>>>
>>>>
>>>> *public* *class* ObjectTest {
>>>>
>>>>      *public* *static* *void* main(String[] args) {
>>>>
>>>>         List<Obj> arrayList = *new* ArrayList<Obj>();
>>>>
>>>>         List<Obj> linkedList = *new* LinkedList<Obj>();
>>>>
>>>>         Map<String, Obj> hashMap = *new* HashMap<String, Obj>();
>>>>
>>>>
>>>>
>>>>         *for*(*int* i = 0; i < 10000; i++) {
>>>>
>>>>             Obj arrayObj = *new* Obj();
>>>>
>>>>             arrayList.add(arrayObj);
>>>>
>>>>         }
>>>>
>>>>
>>>>
>>>>         *for*(*int* i = 0; i < 10000; i++) {
>>>>
>>>>             Obj linkedObj = *new* Obj();
>>>>
>>>>             linkedList.add(linkedObj);
>>>>
>>>>         }
>>>>
>>>>
>>>>
>>>>         *for*(*int* i = 0; i < 10000; i++) {
>>>>
>>>>
>>>>             String str = i + "";
>>>>
>>>>             Obj hashObj = *new* Obj();
>>>>
>>>>             hashMap.put(str, hashObj);
>>>>
>>>>         }
>>>>
>>>>      }
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>> *class* Obj {
>>>>
>>>>      *byte*[] bytes;
>>>>
>>>>      *public* Obj() {
>>>>
>>>>         bytes = *new* *byte*[16];
>>>>
>>>>
>>>>      }
>>>>
>>>>   }
>>>>
>>>>
>>>> ------------------------------**------------------------------**
>>>> ------------------------------**--------
>>>>
>>>> If new gen cannot hold all the objects, GC will occur. I want to know if
>>>> all the items in the data structure are copied into old gen.
>>>>
>>>> For example, arrayList itself exists in old while some of its arrayObjs
>>>> exist in new gen. A arrayObj exists in old gen while its bytes exists in
>>>> new gen.
>>>>
>>>>
>>>>
>>>>
>>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/hotspot-gc-dev/attachments/20130829/90b1880c/attachment.htm>


More information about the hotspot-gc-dev mailing list