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