8209920: runtime/logging/RedefineClasses.java fail with OOME with ZGC
Per Liden
per.liden at oracle.com
Mon Aug 27 10:54:56 UTC 2018
Hi,
On 08/27/2018 12:24 PM, Leonid Mesnik wrote:
> Hi
>
>> On Aug 27, 2018, at 1:05 AM, Per Liden <per.liden at oracle.com
>> <mailto:per.liden at oracle.com>> wrote:
>>
>> Hi Leonid,
>>
>> On 08/24/2018 10:44 PM, Leonid Mesnik wrote:
>>> Hi
>>> Could you please review following fix. I think that fix could be
>>> considered as trivial. So I would like to push it once I get Review
>>> to avoid failures in tier3.
>>> bug: https://bugs.openjdk.java.net/browse/JDK-8209920
>>> diff:
>>> diff -r 9d01ad46daef
>>> test/hotspot/jtreg/runtime/logging/RedefineClasses.java
>>> --- a/test/hotspot/jtreg/runtime/logging/RedefineClasses.java Fri
>>> Aug 24 15:49:21 2018 -0400
>>> +++ b/test/hotspot/jtreg/runtime/logging/RedefineClasses.java Fri
>>> Aug 24 13:23:17 2018 -0700
>>> @@ -26,6 +26,7 @@
>>> * @bug 8197901 8209758
>>> * @summary Redefine classes with enabling logging to verify
>>> Klass:external_name() during GC.
>>> * @comment This test is simplified version of
>>> runtime/RedefineTests/RedefineRunningMethods.java.
>>> + * @requires vm.opt.final.ClassUnloading
>>> * @library /test/lib
>>> * @modules java.compiler
>>> * java.instrument
>>
>> I don't think this addresses the root cause. The test fails because
>> we're running out of heap, not because we didn't unload classes. In
>> other words, the test would still fail if you were running ZGC with
>> class unloading enabled.
>>
>> The problem is that the test is given 256m of heap, and the obj[]
>> array keeps 20 * 10M alive. This will actually occupy 7*32M = 224M of
>> medium ZPages on the heap, which leaves 32M for the rest. However,
>> ZGC's heap reserve is 32M + 2M * nworkers, which means we're out of
>> memory.
>>
>> So, instead of adding the vm.opt.final.ClassUnloading attribute, I'd
>> suggest we reduce the size of the obj[] array to 10 instead of 20.
>> That would leave enough heap available for the test to pass.
> Thanks for good explanation of how memory is used by ZGC. I agree that
> such fix makes test to pass with ZGC
>
> However test doesn't provoke crash described in original bug when
> classes are not unloaded. At least it always pass with ZGC enabled. It
> pass even fix from bug
> https://bugs.openjdk.java.net/browse/JDK-8197901
> is not applied. So I've thought that it is not needed to be run.
>
> The number of attempts to make GC was just used in original
> test runtime/RedefineTests/RedefineRunningMethods.java. It is important
> to run GC more then 10 times to provoke original crash. While test
> does't need to occupy ~200M of live memory to provoke crash. It is
> enough to produce smaller amount of garbage for this, so it would be
> better just to reduce size of byte[] array.
I see.
>
> If you think that it makes sense to run test with ZGC right now then see
> fix below. It might be a still good stress test for combination of
> logging/GC/class[un]loading for any GC.
> I verified that test pass with ZGC and still provokes original crash
> when run with G1.
Since it's a quick test I think it's worth running on all GCs, even if
ZGC doesn't currently do class unloading.
>
> diff -r 9d01ad46daef test/hotspot/jtreg/runtime/logging/RedefineClasses.java
> --- a/test/hotspot/jtreg/runtime/logging/RedefineClasses.java Fri Aug
> 24 15:49:21 2018 -0400
> +++ b/test/hotspot/jtreg/runtime/logging/RedefineClasses.java Mon Aug
> 27 03:01:25 2018 -0700
> @@ -53,7 +53,7 @@
> RedefineClassHelper.redefineClass(RedefineClasses_B.class, newB);
> RedefineClasses_B.test();
> for (int i = 0; i < 20 ; i++) {
> - obj[i] = new byte[10 * 1024 * 1024];
> + obj[i] = new byte[1024 * 1024];
> System.gc();
> }
> }
>
>
> What do you think this fix?
Yep, looks good.
cheers,
Per
>>
>> diff --git a/test/hotspot/jtreg/runtime/logging/RedefineClasses.java
>> b/test/hotspot/jtreg/runtime/logging/RedefineClasses.java
>> --- a/test/hotspot/jtreg/runtime/logging/RedefineClasses.java
>> +++ b/test/hotspot/jtreg/runtime/logging/RedefineClasses.java
>> @@ -42,7 +42,7 @@
>> }
>>
>> public class RedefineClasses {
>> - static Object[] obj = new Object[20];
>> + static Object[] obj = new Object[10];
>> public static String newB =
>> "class RedefineClasses_B {" +
>> " public static void test() { " +
>> @@ -52,7 +52,7 @@
>> public static void main(String[] args) throws Exception {
>> RedefineClassHelper.redefineClass(RedefineClasses_B.class, newB);
>> RedefineClasses_B.test();
>> - for (int i = 0; i < 20 ; i++) {
>> + for (int i = 0; i < obj.length; i++) {
>> obj[i] = new byte[10 * 1024 * 1024];
>> System.gc();
>> }
>>
>> On the other hand, it's not clear to me what the alloc+System.gc()
>> for-loop is trying to accomplish and why it is needed. I can remove
>> the whole for-loop and the test passes anyway, regardless of which GC
>> i pick. Am I missing something?
> The idea is to provoke crash described in the
> https://bugs.openjdk.java.net/browse/JDK-8197901
> It happens during GC with enabled logging. This is why GC is actually
> needed.
>
> Leonid
>>
>> cheers,
>> Per
>
More information about the hotspot-gc-dev
mailing list