11/*
2- * Copyright (c) 2004, 2018 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2004, 2024 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
2929import java .util .List ;
3030import java .util .concurrent .atomic .AtomicReference ;
3131import java .util .concurrent .SynchronousQueue ;
32+ import java .util .concurrent .TimeUnit ;
3233import nsk .share .*;
3334import nsk .share .gc .Algorithms ;
3435import nsk .share .gc .Memory ;
3940public class from001 {
4041
4142 private static boolean testFailed = false ;
43+ private static final int MAX_TRIES = 6 ; // limit attempts to receive Notification data
4244
4345 public static void main (String [] args ) {
4446
@@ -62,8 +64,8 @@ public static void main(String[] args) {
6264
6365 log .display ("null CompositeData check passed." );
6466
65- // 2. Check CompositeData that doest not represnt
66- // MemoryNotificationInfo - IllegalArgumentException must be thrown
67+ // 2. Check CompositeData that does not represent MemoryNotificationInfo
68+ // throws IllegalArgumentException
6769
6870 ObjectName mbeanObjectName = null ;
6971 CompositeData cdata = null ;
@@ -85,12 +87,13 @@ public static void main(String[] args) {
8587 testFailed = true ;
8688 } catch (IllegalArgumentException e ) {
8789
88- // Expected: CompositeData doest not represnt MemoryNotificationInfo
90+ // Expected: CompositeData does not represent MemoryNotificationInfo
8991 }
9092
91- log .display ("check for CompositeData doest not represnt MemoryNotificationInfo passed." );
93+ log .display ("check that CompositeData does not represent MemoryNotificationInfo passed." );
9294
93- // 3. Check correct CompositeData
95+ // 3. Check correct CompositeData usage:
96+ // First try to provoke a Notification on a MemoryPool.
9497 Object poolObject = null ;
9598 try {
9699 mbeanObjectName = new ObjectName (ManagementFactory .MEMORY_MXBEAN_NAME );
@@ -123,7 +126,11 @@ public static void main(String[] args) {
123126 throw new TestFailure ("TEST FAILED. See log." );
124127 }
125128
126- // eat memory just to emmit notification
129+ if (poolObject == null ) {
130+ throw new TestFailure ("No memory pool found to test." );
131+ }
132+
133+ // eat memory just to emit notification
127134 Stresser stresser = new Stresser (args ) {
128135
129136 @ Override
@@ -133,41 +140,57 @@ public boolean continueExecution() {
133140 }
134141 };
135142 stresser .start (0 );// we use timeout, not iterations
136- GarbageUtils .eatMemory (stresser );
137-
138- boolean messageNotRecieved = true ;
139- while (messageNotRecieved ) {
143+ int oomCount = GarbageUtils .eatMemory (stresser );
144+ log .display ("eatMemory returns OOM count: " + oomCount );
145+
146+ // Check for the message. Poll on queue to avoid waiting forver on failure.
147+ // Notification is known to fail, very rarely, with -Xcomp where the allocations
148+ // do not affect the monitored pool. Possibly a timing issue, where the "eatMemory"
149+ // is done before Notification/threshold processing happens.
150+ // The Notification is quite immediate, other than that problem.
151+ boolean messageReceived = false ;
152+ int tries = 0 ;
153+ while (!messageReceived && ++tries < MAX_TRIES ) {
140154 try {
141- from001Listener .queue .take ();
142- messageNotRecieved = false ;
155+ Object r = from001Listener .queue .poll (10000 , TimeUnit .MILLISECONDS );
156+ if (r == null ) {
157+ log .display ("poll for Notification data returns null..." );
158+ continue ;
159+ } else {
160+ messageReceived = true ;
161+ break ;
162+ }
143163 } catch (InterruptedException e ) {
144- messageNotRecieved = true ;
164+ // ignored, continue
145165 }
146166 }
147167
168+ // If we got a Notification, test that the CompositeData can create a MemoryNotificationInfo
169+ if (!messageReceived ) {
170+ throw new TestFailure ("No Notification received." );
171+ }
148172 result = MemoryNotificationInfo .from (from001Listener .data .get ());
149173 try {
150- ObjectName poolObjectName = new ObjectName (monitor .getName (poolObject ));
151- ObjectName resultObjectName = new ObjectName (
152- ManagementFactory .MEMORY_POOL_MXBEAN_DOMAIN_TYPE +
153- ",name=" + result .getPoolName ());
154-
155- log .display ("poolObjectName : " + poolObjectName +
156- " resultObjectName : " + resultObjectName );
157-
158- if (!poolObjectName .equals (resultObjectName )) {
159- log .complain ("FAILURE 3." );
160- log .complain ("Wrong pool name : " + resultObjectName +
161- ", expected : " + poolObjectName );
162- testFailed = true ;
163- }
174+ ObjectName poolObjectName = new ObjectName (monitor .getName (poolObject ));
175+ ObjectName resultObjectName = new ObjectName (
176+ ManagementFactory .MEMORY_POOL_MXBEAN_DOMAIN_TYPE +
177+ ",name=" + result .getPoolName ());
178+
179+ log .display ("poolObjectName : " + poolObjectName +
180+ " resultObjectName : " + resultObjectName );
181+
182+ if (!poolObjectName .equals (resultObjectName )) {
183+ log .complain ("FAILURE 3." );
184+ log .complain ("Wrong pool name : " + resultObjectName +
185+ ", expected : " + poolObjectName );
186+ testFailed = true ;
187+ }
164188
165189 } catch (Exception e ) {
166190 log .complain ("Unexpected exception " + e );
167191 e .printStackTrace (log .getOutStream ());
168192 testFailed = true ;
169193 }
170-
171194 if (testFailed ) {
172195 throw new TestFailure ("TEST FAILED. See log." );
173196 }
@@ -183,17 +206,21 @@ class from001Listener implements NotificationListener {
183206 static SynchronousQueue <Object > queue = new SynchronousQueue <Object >();
184207
185208 public void handleNotification (Notification notification , Object handback ) {
186- if (data .get () != null )
209+ if (data .get () != null ) {
210+ System .out .println ("handleNotification: ignoring" );
187211 return ;
188- data .set ((CompositeData ) notification .getUserData ());
212+ }
213+ System .out .println ("handleNotification: getting data" );
214+ CompositeData d = (CompositeData ) notification .getUserData ();
215+ data .set (d );
189216
190217 boolean messageNotSent = true ;
191218 while (messageNotSent ){
192219 try {
193220 queue .put (new Object ());
194221 messageNotSent = false ;
195222 } catch (InterruptedException e ) {
196- messageNotSent = true ;
223+ // ignore, retry
197224 }
198225 }
199226 }
0 commit comments