[10] RFR for JDK-8170299: Debugger does not stop inside the low memory notifications code [internal]

David Holmes david.holmes at oracle.com
Mon Dec 11 12:40:00 UTC 2017


Hi Shafi,

I'm not at all sure about the approach you've taken with this ...

On 11/12/2017 8:31 PM, Shafi Ahmad wrote:
> Hi,
> 
> Could you please review the fix for JDK-8170299: Debugger does not stop 
> inside the low memory notifications code.
> 
> With the current implementation ‘debugger does not stop inside the low 
> memory *notifications* code’
> 
> This is expected as the notification code is getting executed with the 
> service thread, which is a hidden thread.

Okay. I recall some discussion on this problem - the main question being 
"why is the service thread executing user-defined Java code?". I'm 
assuming now this is an implementation artifact, not part of the main 
design of the management framework? But it is unclear. Attempting to 
introduce a new thread to execute the code may be reasonable, but raises 
  whole range of questions about concurrency, synchronization and 
possibly deadlock with this code!

> shafi at shafi-ahmad:~/Java/jdk8/jdk8u-dev$ jdb -Xmx32m MemoryWarningSystem
> 
> Initializing jdb ...
> 
>  > stop at MemoryWarningSystem$1:25
> 
> Deferring breakpoint MemoryWarningSystem$1:25.
> 
> It will be set after the class is loaded.
> 
>  > run
> 
> run MemoryWarningSystem
> 
> Set uncaught java.lang.Throwable
> 
> Set deferred uncaught java.lang.Throwable
> 
>  >
> 
> . . .
> 
>  > quit
> 
> Breakpoint not hit.
> 
> With the attached webrev, jdb stop  at breakpoint inside notification code.
> 
> shshahma at slc12kkg:/scratch/shshahma/Java/jdk-dev$ jdb -Xmx128m 
> MemoryWarningSystem
> 
> Initializing jdb ...
> 
>  > stop at MemoryWarningSystem$1:25
> 
> Deferring breakpoint MemoryWarningSystem$1:25.
> 
> It will be set after the class is loaded.
> 
>  > run
> 
> run MemoryWarningSystem
> 
> Set uncaught java.lang.Throwable
> 
> Set deferred uncaught java.lang.Throwable
> 
>  >
> 
> VM Started: Set deferred breakpoint MemoryWarningSystem$1:25
> 
> Breakpoint hit: "thread=Debugger", 
> MemoryWarningSystem$1.memoryUsageLow(), line=25 bci=0
> 
> 25            System.out.println("Memory usage low!!!");
> 
> Debugger[1] where
> 
>    [1] MemoryWarningSystem$1.memoryUsageLow (MemoryWarningSystem.java:25)
> 
>    [2] MemoryWarningSystem$2.handleNotification 
> (MemoryWarningSystem.java:48)
> 
>    [3] 
> javax.management.NotificationBroadcasterSupport.handleNotification 
> (NotificationBroadcasterSupport.java:284)
> 
>    [4] javax.management.NotificationBroadcasterSupport$SendNotifJob.run 
> (NotificationBroadcasterSupport.java:361)
> 
>    [5] java.util.concurrent.ThreadPoolExecutor.runWorker 
> (ThreadPoolExecutor.java:1,135)
> 
>    [6] java.util.concurrent.ThreadPoolExecutor$Worker.run 
> (ThreadPoolExecutor.java:635)
> 
>    [7] java.lang.Thread.run (Thread.java:844)
> 
>    [8] jdk.internal.misc.InnocuousThread.run (InnocuousThread.java:134)
> 
> Debugger[1] list
> 
> 21
> 
> 22        MemoryWarningSystem mws = new MemoryWarningSystem();
> 
> 23        mws.addListener(new MemoryWarningSystem.Listener() {
> 
> 24          public void memoryUsageLow(long usedMemory, long maxMemory) {
> 
> 25 =>         System.out.println("Memory usage low!!!");
> 
> 26            double percentageUsed = ((double) usedMemory) / maxMemory;
> 
> 27            System.out.println("percentageUsed = " + percentageUsed);
> 
> 28            MemoryWarningSystem.setPercentageUsageThreshold(0.8);
> 
> 29          }
> 
> 30        });
> 
> Debugger[1] threads
> 
> Group system:
> 
>    (java.lang.ref.Reference$ReferenceHandler)0x362 Reference Handler running
> 
>    (java.lang.ref.Finalizer$FinalizerThread)0x361  Finalizer         
> cond. waiting
> 
>    (java.lang.Thread)0x360                         Signal Dispatcher running
> 
> Group main:
> 
>    (java.lang.Thread)0x1                           main              running
> 
> Group InnocuousThreadGroup:
> 
>    (jdk.internal.misc.InnocuousThread)0x35f        Common-Cleaner    
> cond. waiting
> 
>    (jdk.internal.misc.InnocuousThread)0x4f1        Debugger   
>         running (at breakpoint)
> 
> Debugger[1] step
> 
>  > Memory usage low!!!
> 
> Step completed: "thread=Debugger", 
> MemoryWarningSystem$1.memoryUsageLow(), line=26 bci=8
> 
> 26            double percentageUsed = ((double) usedMemory) / maxMemory;
> 
> Please see the newly created thread “  
> (jdk.internal.misc.InnocuousThread)0x4f1        Debugger   
>         running (at breakpoint)”.
> 
> In the change, the class ‘MemoryImpl’ is derived from class 
> ‘NotificationBroadcasterSupport’ instead of class 
> ‘NotificationEmitterSupport’

That's quite a significant change and the implications of it are not at 
all obvious. The sun.management.NotificationEmitterSupport class 
utilises synchronization for thread-safety. The 
NotificationBroadcasterSupport class utilises a CopyOnWriteArraylist and 
will have quite different concurrency properties. Throw into the mix the 
fact you've now added a new thread and we really have no clear idea how 
this will all behave.

> NotificationBroadcastSupport takes an Executor, in the constructor of 
> MemoryImpl we are calling super() with an executor, which is a visible 
> thread.
> 
> The method hasListeners() is referenced  inside MemoryImpl.java and 
> defined in  NotificationEmitterSupport.
> 
> This method is not present in  NotificationBroadcasterSupport so I added 
> it to NotificationBroadcasterSupport.

You will need to file a CSR request first to add a public method to a 
public class. But it's not all clear to me this is a method that should 
be added to this API.

I see what you are trying to do, but the impact of these changes seem 
quite far reaching and hard to determine.

> Jdk10 bug: https://bugs.openjdk.java.net/browse/JDK-8170299

You should note that the bug is not publicly visible.

Thanks,
David

> Webrev link: http://cr.openjdk.java.net/~shshahma/8170299/webrev.02/
> 
> Testing: jprt -testset core, rbt --test nsk.jvmti.testlist,nsk.jdi.testlist.
> 
> Regards,
> 
> Shafi
> 


More information about the serviceability-dev mailing list