<div dir="ltr"><div>> This could severely affect performance. One might create an ArrayList and use</div>ArrayList.ensureCapacity before adding a large number of elements, to reduce<br>incremental resizing of the internal array. Then you propose the GC can come<br><div>along and stomp on your capacity setting.</div><div><br></div><div>Yes, I am aware of this. This is why I am proposing 3 modes: off, idle, and always. The default mode will be off until enough performance testing shows that idle is good for most programs. I realize that some programs may need to turn it off.<br></div><div><br></div><div>In idle mode, this begs the question in what case can GC trim the ArrayList and the Java program call ArrayList.ensureCapacity()? The Java program is by definition idle. So, it isn't calling ArrayList.ensureCapacity().</div><div><br></div><div></div><div>In always mode, this is the exact thing I am concerned about. Please see my "Notes" section in a previous email today that discusses this. I doubt that always mode will be viable without additional work.<br></div><div><br></div><div>> One can use ArrayList.trimToSize to eliminate excess capacity.</div><div><br></div><div>We need the program code to call trimToSize() or we would have to add synchronization to ArrayList. Adding synchronization will incur a huge synchronization cost.</div><div><br></div><div>The beauty of trimming in GC relocation is that the synchronization is taken care of by the GC relocation algorithm. For Serial, Parallel, and G1, the relocation happens during program pause and the pause is the synchronization. For ZGC, the relocation algorithm is executed by GC and Java threads. The relocation algorithm provides the synchronization. See my previous email today on how this relocation algorithm needs to be tweaked.<br></div><div><br></div><div>> HashMap performance depends on having excess capacity to reduce collisions.</div>The HashMap constructor has an argument that is a hint of the expected number<br>of entries. If your HashMaps are overly sparse you can either use a smaller<br><div>initial hint or copy into a new "right-sized" map.</div><div><br></div><div>HashMap uses a load factor to determine when the internal hashtable needs to be increased in size to reduce collisions. The trimming follows this load factor and won't trim the hashtable smaller than what the load factor dictates.</div><div><br></div><div>> I don't know how the GC could possibly reduce a HashMap, since the positions</div><div>of entries depend on information that the GC doesn't have nor can compute.</div><div><br></div><div>Please see my previous email today on how this works.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jan 24, 2023 at 4:31 AM Kim Barrett <<a href="mailto:kim.barrett@oracle.com">kim.barrett@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">> On Jan 23, 2023, at 12:44 PM, Nathan Reynolds <<a href="mailto:numeralnathan@gmail.com" target="_blank">numeralnathan@gmail.com</a>> wrote:<br>
> <br>
> > 1. Such a change would have user observable differences in behaviour, which could introduce bugs in user code, due to the optimization.<br>
> <br>
> How is this user observable? The Object[] is buried inside an ArrayList or HashMap. This idea is not touching other Object[]'s outside a collection.<br>
<br>
This could severely affect performance. One might create an ArrayList and use<br>
ArrayList.ensureCapacity before adding a large number of elements, to reduce<br>
incremental resizing of the internal array. Then you propose the GC can come<br>
along and stomp on your capacity setting.<br>
<br>
One can use ArrayList.trimToSize to eliminate excess capacity.<br>
<br>
HashMap performance depends on having excess capacity to reduce collisions.<br>
The HashMap constructor has an argument that is a hint of the expected number<br>
of entries. If your HashMaps are overly sparse you can either use a smaller<br>
initial hint or copy into a new "right-sized" map.<br>
<br>
I don't know how the GC could possibly reduce a HashMap, since the positions<br>
of entries depend on information that the GC doesn't have nor can compute.<br>
<br>
> I suppose a performance impact from having to grow is somewhat observable. This was noted in my original email. However, growing is not functionally observable.<br>
<br>
Not functionally observable != not important for users.<br>
<br>
</blockquote></div>