On Mon, 18 Jul 2022 07:40:53 GMT, Aleksey Shipilev <sh...@openjdk.org> wrote:

> Test appears to pass fine with G1. But it fails with other GCs, for example 
> Parallel, Shenandoah, etc, it fails:
> 
> 
> $ CONF=linux-x86_64-server-fastdebug make test 
> TEST=java/io/ObjectStreamClass/ObjectStreamClassCaching.java 
> TEST_VM_OPTS="-XX:+UseParallelGC"
> 
> test ObjectStreamClassCaching.testCacheReleaseUnderMemoryPressure(): success
> test ObjectStreamClassCaching.testCachingEffectiveness(): failure
> java.lang.AssertionError: Cache lost entry although memory was not under 
> pressure expected [false] but found [true]
>       at org.testng.Assert.fail(Assert.java:99)
>       at org.testng.Assert.failNotEquals(Assert.java:1037)
>       at org.testng.Assert.assertFalse(Assert.java:67)
> 
> 
> I believe this is because `System.gc()` is not that reliable about what 
> happens with weak references. As seen with other GCs, they can clear the 
> weakrefs on Full GC. In fact, the test fails with G1 if we do a second 
> System.gc() in this test. So the test itself is flaky. The fix is to avoid 
> doing `System.gc()` altogether in that subtest. The test is still retained to 
> see that reference is not cleared for a while.
> 
> Additional testing:
>  - [x] Linux x86_64 fastdebug, affected test with `-XX:+UseSerialGC`, 100 
> repetitions
>  - [x] Linux x86_64 fastdebug, affected test with `-XX:+UseParallelGC`, 100 
> repetitions
>  - [x] Linux x86_64 fastdebug, affected test with `-XX:+UseG1GC`, 100 
> repetitions
>  - [x] Linux x86_64 fastdebug, affected test with `-XX:+UseShenandoahGC`, 100 
> repetitions
>  - [x] Linux x86_64 fastdebug, affected test with `-XX:+UseZGC`, 100 
> repetitions

...my above claims might appear strange to some reader as the test clearly 
wraps a cached ObjectStreamClass instance with a  WeakReference and then checks 
whether this WeakReference is cleared or not. So an explanation is in order... 
The internal cache uses SoftReference(s). Since the cache is encapsulated, the 
test does not check it directly but uses a trick. It wraps the cached instance 
with a WeakReference. Since the instance is already wrapped with SoftReference 
in the cache and there is no strong reference holding it, the instance can be 
considered Softly Reachable. And we know that GC must clear all XxxReference(s) 
regardless of their type pointing to the same referent atomically. By detecting 
in the test that a WeakReference is cleared, we assume that the internal 
SoftReference is cleared too. If this was not the case, GC could be considdered 
to have a bug and is not by the spec. So what we are observing now is either 
System.gc() clearing SoftReference or a GC bug. I don't bel
 ive it is a GC bug though.

-------------

PR: https://git.openjdk.org/jdk/pull/9533

Reply via email to