[jdk21u-dev] RFR: 8337994: [REDO] Native memory leak when not recording any events

Goetz Lindenmaier goetz at openjdk.org
Thu Dec 12 07:14:37 UTC 2024


On Mon, 11 Nov 2024 18:17:06 GMT, Boris Ulasevich <bulasevich at openjdk.org> wrote:

>> Reproducer:
>> 
>> import jdk.jfr.consumer.RecordingStream;
>> 
>> /**
>>   * Stress test to provoke the memory leak:
>>   * starts 1M empty threads in VM with jfr recording
>>   */
>> public class PinnedThreadTracker implements AutoCloseable
>> {
>>     private final RecordingStream recordingStream;
>> 
>>     public PinnedThreadTracker() {
>>         recordingStream = new RecordingStream();
>>         recordingStream.startAsync();
>>         System.out.println("start recording..");
>>     }
>> 
>>     @Override
>>     public void close() {
>>         recordingStream.close();
>>     }
>> 
>>     class MyThread extends Thread {
>>         public void run() {
>>         }
>>     }
>>     public void runThreads() {
>>         for (int i = 0; i < 100; i++) {
>>             for (int j = 0; j < 100; j++) {
>>                 for (int k = 0; k < 100; k++) {
>>                     new MyThread().start();
>>                 }
>>                 MyThread thr = new MyThread(); thr.start();
>>                 try {
>>                     thr.join();
>>                 } catch (Exception ex) {}
>>             }
>>             System.out.print(".");
>>         }
>>     }
>> 
>>     public static void main(String a[]) {
>>         PinnedThreadTracker ptt = new PinnedThreadTracker();
>>         ptt.runThreads();
>>         ptt.close();
>>     }
>> }	
>> 
>> 
>> Manual testing results on jdk21u:
>> 
>> $ for i in {0..60}; do
>>     export PID=`ps -ax | grep java | grep PinnedThreadTracker | sed "s/^ *// ; s/ .*//"`
>>     jcmd $PID VM.native_memory | grep Tracing.*reserved
>>     sleep 1s
>>   done
>> 
>> Before the change (jcmd VM.native_memory output once a second):
>> -                   Tracing (reserved=17355KB, committed=17355KB)
>> -                   Tracing (reserved=21646KB, committed=21646KB)
>> -                   Tracing (reserved=25870KB, committed=25870KB)
>> -                   Tracing (reserved=30065KB, committed=30065KB)
>> ...
>> -                   Tracing (reserved=240567KB, committed=240567KB)
>> -                   Tracing (reserved=244519KB, committed=244519KB)
>> -                   Tracing (reserved=248525KB, committed=248525KB)
>> -                   Tracing (reserved=252527KB, committed=252527KB)
>> 
>> With the fix:
>> -                   Tracing (reserved=17655KB, committed=17655KB)
>> -                   Tracing (reserved=18125KB, committed=18125KB)
>> -                   Tracing (reserved=18449KB, committed=18449KB)
>> -                   Tracing (reserved=18961KB, committed=18961KB)
>> ...
>> -                 ...
>
>> Hi @bulasevich, can this wait for the April update? It would get some more test coverage.
> 
> Hi @GoeLin 
> In my opinion, this bug could have a significant impact on customers, and it would be ideal to fix it as soon as possible. However, I understand that some reasonable patience is necessary. I'm not opposed to waiting for the next update.

Hi @bulasevich 
is it possible that your push breaks jdk/jfr/jvm/TestChunkIntegrity.java ?
We see this failing in our CI tonight on all platforms. 
I'll try to reproduce it locally and verify whether it's your change.


Veryfying chunk: disassembled/recording_00.jfr 0
Veryfying chunk: disassembled/recording_01.jfr 3338
Veryfying chunk: disassembled/recording_02.jfr 9083
One value null
Value A: {
  type = N/A
  name = "bootstrap"
}

Value B: null
Field classLoader doesn't match
Value A: {
  type = N/A
  name = "bootstrap"
}

Value B: null
Field type doesn't match
Value A: {
  classLoader = null
  name = "jdk/internal/loader/ClassLoaders$AppClassLoader"
  package = {
    name = "jdk/internal/loader"
    module = {
      name = "java.base"
      version = "21.0.7-internal"
      location = "jrt:/java.base"
      classLoader = null
    }
    exported = true
  }
  modifiers = 10
  hidden = false
}

Value B: {
  classLoader = N/A
  name = "jdk/internal/loader/ClassLoaders$AppClassLoader"
  package = {
    name = "jdk/internal/loader"
    module = {
      name = "java.base"
      version = "21.0.7-internal"
      location = "jrt:/java.base"
      classLoader = N/A
    }
    exported = true
  }
  modifiers = 10
  hidden = false
}

Field classLoader doesn't match
Value A: {
  type = jdk.internal.loader.ClassLoaders$AppClassLoader (classLoader = bootstrap)
  name = "app"
}

Value B: {
  type = jdk.internal.loader.ClassLoaders$AppClassLoader (classLoader = null)
  name = "app"
}

Field type doesn't match
Value A: {
  classLoader = jdk.internal.loader.ClassLoaders$AppClassLoader (id = 3)
  name = "jdk/jfr/jvm/TestChunkIntegrity$ClassStressor"
  package = {
    name = "jdk/jfr/jvm"
    module = {
      name = N/A
      version = N/A
      location = N/A
      classLoader = jdk.internal.loader.ClassLoaders$AppClassLoader (id = 3)
    }
    exported = true
  }
  modifiers = 8
  hidden = false
}

Value B: {
  classLoader = jdk.internal.loader.ClassLoaders$AppClassLoader (id = 3)
  name = "jdk/jfr/jvm/TestChunkIntegrity$ClassStressor"
  package = {
    name = "jdk/jfr/jvm"
    module = {
      name = N/A
      version = N/A
      location = N/A
      classLoader = jdk.internal.loader.ClassLoaders$AppClassLoader (id = 3)
    }
    exported = true
  }
  modifiers = 8
  hidden = false
}

Field method doesn't match
Value A: {
  type = jdk.jfr.jvm.TestChunkIntegrity$ClassStressor (classLoader = app)
  name = "stress"
  descriptor = "()V"
  modifiers = 4
  hidden = false
}

Value B: {
  type = jdk.jfr.jvm.TestChunkIntegrity$ClassStressor (classLoader = app)
  name = "stress"
  descriptor = "()V"
  modifiers = 4
  hidden = false
}

Array contents doesn't match
Field frames doesn't match
Value A: [Ljava.lang.Object;@16e87903
Value B: [Ljava.lang.Object;@466281af
Object A:
Clazz {
  startTime = 01:26:04.779 (2024-12-12)
  clazz = jdk.jfr.jvm.TestChunkIntegrity$MyClass (classLoader = JFR TestClassLoader)
  eventThread = "Thread-1" (javaThreadId = 33)
  stackTrace = [
    jdk.jfr.jvm.TestChunkIntegrity$ClassStressor.stress() line: 272
    jdk.jfr.jvm.TestChunkIntegrity$StressThread.run() line: 75
  ]
}


Object B:
Clazz {
  startTime = 01:26:04.779 (2024-12-12)
  clazz = jdk.jfr.jvm.TestChunkIntegrity$MyClass (classLoader = JFR TestClassLoader)
  eventThread = "Thread-1" (javaThreadId = 33)
  stackTrace = [
    jdk.jfr.jvm.TestChunkIntegrity$ClassStressor.stress() line: 272
    jdk.jfr.jvm.TestChunkIntegrity$StressThread.run() line: 75
  ]
}


----------System.err:(12/755)----------
java.lang.AssertionError: Events don't match. Event number 0
	at jdk.jfr.jvm.TestChunkIntegrity.assertEventEquals(TestChunkIntegrity.java:174)
	at jdk.jfr.jvm.TestChunkIntegrity.main(TestChunkIntegrity.java:131)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at com.sun.javatest.regtest.agent.MainWrapper$MainTask.run(MainWrapper.java:138)
	at java.base/java.lang.Thread.run(Thread.java:1583)

JavaTest Message: Test threw exception: java.lang.AssertionError: Events don't match. Event number 0
JavaTest Message: shutting down test

STATUS:Failed.`main' threw exception: java.lang.AssertionError: Events don't match. Event number 0

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

PR Comment: https://git.openjdk.org/jdk21u-dev/pull/1095#issuecomment-2537988846


More information about the jdk-updates-dev mailing list