<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>As Roger mentioned, there is a ForceGC utility in the test
      library:</p>
    <p>    test/lib/jdk/test/lib/util/ForceGC.java</p>
    <p>and it's used in a variety of places in the core libs tests.
      Essentially it sets up a PhantomReference and a ReferenceQueue and
      runs System.gc() in a loop. I'd strongly recommend using this in
      preference to allocating a lot of memory in order to provoke
      OutOfMemoryError. That technique has historically been a cause of
      test flakiness, and it still is, as you've discovered.</p>
    <p>There is also MemoryMXBean.gc(), which does the same thing
      System.gc() does -- it calls Runtime.getRuntime().gc().<br>
    </p>
    <p>It's true that System.gc() may sometimes be ignored -- for
      instance if Epsilon GC is enabled -- but for practical purposes,
      on Hotspot using a standard collector, calling it will eventually
      cause garbage collection and reference processing.</p>
    <p>If at some point the behavior provided by System.gc() is
      inadequate for our testing, we'll need to plumb a JDK-specific
      interface that has stronger semantics, and then convert ForceGC to
      use it so that individual tests won't have to be updated.</p>
    <p>There are still some tests that allocate lots of memory in order
      to provoke OOME and consequently reference processing. They
      probably need to be run in /othervm mode in order to set custom
      heap sizes and to avoid interfering with other tests. It would be
      interesting to see if those could be adjusted to use something
      ForceGC so that they can share the JVM with other tests and also
      avoid allocating lots of memory.<br>
    </p>
    <p>s'marks<br>
    </p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 3/3/23 10:02 AM, Aleksei Ivanov
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:db78c97d-9ba9-ccf0-a751-9dbc8b2c5ecc@oracle.com">
      
      Hello,<br>
      <br>
      In clientlibs, there's occasionally a need to verify an object
      isn't leaked. For this purpose, WeakReference or PhantomReference
      is used.<br>
      <br>
      Then, we need to make the reference object be cleared, so a GC
      cycle need to be triggered. The common approach is generating
      OutOfMemoryError, catching it and verifying whether the reference
      is cleared.<br>
      <br>
      Some tests use a utility method regtesthelpers/Util.<span class="pl-en">generateOOME [1].</span><br>
      <br>
      For example, these tests follow the above approach:<br>
      <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/blob/master/test/jdk/javax/swing/border/TestTitledBorderLeak.java" moz-do-not-send="true">https://github.com/openjdk/jdk/blob/master/test/jdk/javax/swing/border/TestTitledBorderLeak.java</a><br>
      <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/blob/master/test/jdk/java/awt/List/ListGarbageCollectionTest/AwtListGarbageCollectionTest.java" moz-do-not-send="true">https://github.com/openjdk/jdk/blob/master/test/jdk/java/awt/List/ListGarbageCollectionTest/AwtListGarbageCollectionTest.java</a><br>
      <br>
      <br>
      The AwtListGarbageCollectionTest.java test started to fail pretty
      often in the end of January 2023.<br>
      <br>
      I followed a piece of advice provided in a JBS comment for
      JDK-8300727 [2] and replaced generating OOME with a simple call to
      System.gc() along with adding a loop for re-trying.<br>
      <br>
      The specification for System.gc() [3] mentions that this call can
      be ignored, which started a discussion in the PR #12594 [4] that
      System.gc() should not be used, at the very least without
      generating OOME in addition to invoking System.gc().<br>
      <br>
      At the same time, many tests for Reference objects, such as
      ReferenceEnqueue.java [5] and PhantomReferentClearing.java [6],
      rely solely on System.gc.<br>
      <br>
      <br>
      What would be your recommendation? Are there best practices in
      core-libs and hotspot for testing for memory leaks that clientlibs
      should follow?<br>
      <br>
      <br>
      -- <br>
      Regards,<br>
      Alexey<br>
      <br>
      [1]
      <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/blob/29ee7c3b70ded8cd124ca5b4a38a2aee7c39068b/test/jdk/javax/swing/regtesthelpers/Util.java#L87" moz-do-not-send="true">https://github.com/openjdk/jdk/blob/29ee7c3b70ded8cd124ca5b4a38a2aee7c39068b/test/jdk/javax/swing/regtesthelpers/Util.java#L87</a><br>
      [2] <a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-8300727" moz-do-not-send="true">https://bugs.openjdk.org/browse/JDK-8300727</a><br>
      [3]
      <a class="moz-txt-link-freetext" href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/System.html#gc()" moz-do-not-send="true">https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/System.html#gc()</a><br>
      [4] <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/pull/12594" moz-do-not-send="true">https://github.com/openjdk/jdk/pull/12594</a><br>
      [5]
      <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/blob/f612dcfebea7ffd4390f833646ad45d6f0ebd04f/test/jdk/java/lang/ref/ReferenceEnqueue.java#L54-L60" moz-do-not-send="true">https://github.com/openjdk/jdk/blob/f612dcfebea7ffd4390f833646ad45d6f0ebd04f/test/jdk/java/lang/ref/ReferenceEnqueue.java#L54-L60</a><br>
      [6]
      <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/blob/f612dcfebea7ffd4390f833646ad45d6f0ebd04f/test/jdk/java/lang/ref/PhantomReferentClearing.java#L85-L92" moz-do-not-send="true">https://github.com/openjdk/jdk/blob/f612dcfebea7ffd4390f833646ad45d6f0ebd04f/test/jdk/java/lang/ref/PhantomReferentClearing.java#L85-L92</a><br>
    </blockquote>
  </body>
</html>