<div dir="ltr">Hi Alexey,<br><br>looks good.<br><br>In your test you could set the initial metaspace size to a small size too for added effect, this triggers a lot of resizing early on (eg -XX:MetaspaceSize=1m).<br><br>nit: EpsilonHeap::print_metaspace_info(): I assume this cannot be called before metaspace is set up. Still, would prefer checking for reserved=0 before printing the percentages.<div><br></div><div>Cheers, Thomas</div><div><br><br> <br><br>On Wed, Jan 16, 2019 at 6:23 PM Aleksey Shipilev <<a href="mailto:shade@redhat.com">shade@redhat.com</a>> wrote:<br>><br>> RFE:<br>>   <a href="https://bugs.openjdk.java.net/browse/JDK-8217014">https://bugs.openjdk.java.net/browse/JDK-8217014</a><br>><br>> Fix:<br>>   <a href="http://cr.openjdk.java.net/~shade/8217014/webrev.01/">http://cr.openjdk.java.net/~shade/8217014/webrev.01/</a><br>><br>> While Epsilon does not do the GC collection cycles, Metadata GC machinery is external to it.<br>> Notably, CollectedHeap::satisfy_failed_metadata_allocation would initiate its own VM operation and<br>> call CollectedHeap::collect_as_vm_thread(GCCause::_metadata_GC_threshold) inside of it. All other<br>> GCs would eventually call MetaspaceGC::compute_new_size during that collection cycle. Epsilon would<br>> not, because it currently ignores the GC requests wholesale.<br>><br>> Since MetaspaceGC::compute_new_size is not called, metaspace would resize a little, but would<br>> re-enter satisfy_failed_metadata_allocation and call for safepoint again rather soon, because the<br>> increment was small. You can see that as the flurry of "Metadata GC Threshold" requests ignored by<br>> Epsilon.<br>><br>> The easy way out is to "handle" the metadata GC requests and call the resize in Epsilon. The change<br>> also hooks up Metadata printing to the GC logging, and adds the test that creates lots of classes to<br>> verify. The example log for new jtreg test:<br>><br>> [0.003s][info][gc] Non-resizeable heap; start/max: 128M<br>> [0.003s][info][gc] Using TLAB allocation; max: 4096K<br>> [0.003s][info][gc] Elastic TLABs enabled; elasticity: 1.10x<br>> [0.003s][info][gc] Elastic TLABs decay enabled; decay time: 1000ms<br>> [0.003s][info][gc] Using Epsilon<br>> [0.279s][info][gc] Heap: 128M reserved, 128M (100.00%) committed, 6M (5.24%) used<br>> [0.945s][info][gc          ] Heap: 128M reserved, 128M (100.00%) committed, 39M (30.64%) used<br>> [0.945s][info][gc,metaspace] Metaspace: 36M reserved, 15M (44.10%) committed, 14M (40.62%) used<br>> [1.225s][info][gc          ] GC request for "Metadata GC Threshold" is handled<br>> [1.225s][info][gc,metaspace] Metaspace: 38M reserved, 20M (54.73%) committed, 19M (51.48%) used<br>> [1.326s][info][gc          ] Heap: 128M reserved, 128M (100.00%) committed, 64M (50.17%) used<br>> [1.326s][info][gc,metaspace] Metaspace: 40M reserved, 25M (64.18%) committed, 24M (60.64%) used<br>> <end><br>><br>> For more realistic example, before the change the startup of springboot-petclinic with Epsilon does<br>> 110 (!) "Metadata GC Threshold" requests in first 5 seconds, each of those in its own safepoint.<br>> After this change we only do 3 requests, and thus significantly less safepoints.<br>><br>> Testing: hotspot tier1, gc/epsilon, jdk-submit, new test<br>><br>> Thanks,<br>> -Aleksey</div></div>