blob: 9e7e3d3800f6e56a760da1820ab24b15352b0689 [file] [log] [blame]
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package nsk.monitoring.share;
import java.lang.management.*;
import javax.management.*;
import javax.management.openmbean.*;
import java.util.*;
import nsk.share.*;
/**
* <code>MemoryMonitor</code> class is a wrapper of <code>MemoryMXBean</code> and
* <code>MemoryPoolMXBean</code> interfaces. Depending on command line arguments,
* an instance of this class redirects invocations to the
* <code>MemoryMXBean</code> (or <code>MemoryPoolMXBean</code>) interface. If
* <code>-testMode="directly"</code> option is set, this instance directly
* invokes corresponding method of the <code>MemoryMXBean</code> (or
* <code>MemoryPoolMXBean</code>) interface. If <code>-testMode="server"</code>
* option is set it will make invocations via MBeanServer.
*
* @see ArgumentHandler
*/
public class MemoryMonitor extends Monitor implements NotificationListener,
NotificationFilter {
// Constants to define type of memory that will be allocated in
// MemoryMonitor. For heap memory objects will be allocated; for nonheap
// type classes will be loaded; for mixed type -- both (objects will be
// allocated and classes will be loaded).
public final static String HEAP_TYPE = "heap";
public final static String NONHEAP_TYPE = "nonheap";
public final static String MIXED_TYPE = "mixed";
// Names of the attributes of MemoryMXBean
private final static String POOL_TYPE = "Type";
private final static String POOL_RESET_PEAK = "resetPeakUsage";
private final static String POOL_PEAK = "PeakUsage";
private final static String POOL_VALID = "Valid";
private final static String POOL_U = "Usage";
private final static String UT = "UsageThreshold";
private final static String UT_COUNT = "UsageThresholdCount";
private final static String UT_SUPPORT = "UsageThresholdSupported";
private final static String UT_EXCEEDED = "UsageThresholdExceeded";
private final static String POOL_CU = "CollectionUsage";
private final static String CT = "CollectionUsageThreshold";
private final static String CT_COUNT = "CollectionUsageThresholdCount";
private final static String CT_SUPPORT = "CollectionUsageThresholdSupported";
private final static String CT_EXCEEDED = "CollectionUsageThresholdExceeded";
// Varibales to store options that are passed to the test
private static String memory;
private static int mode;
private static boolean isNotification;
private static boolean isUsageThreshold;
private static volatile boolean passed = true;
private Polling polling = new Polling();
static {
Monitor.logPrefix = "MemoryMonitor > ";
}
/**
* Creates a new <code>MemoryMonitor</code> object.
*
* @param log <code>Log</code> object to print info to.
* @param handler <code>ArgumentHandler</code> object that saves
* all info about test's arguments.
*
*/
public MemoryMonitor(Log log, ArgumentHandler handler) {
super(log, handler);
memory = handler.getTestedMemory();
mode = getTestMode();
isNotification = (handler.MON_NOTIF.equals(handler.getMonitoring()));
isUsageThreshold = (handler.TH_USAGE.equals(handler.getThreshold()));
String s = "\t(This setting is used in lowmem* tests only)";
display("Memory:\t" + handler.getTestedMemory() + s);
display("Monitoring:\t" + handler.getMonitoring() + s);
display("Threshold:\t" + handler.getThreshold() + s);
display("Timeout:\t" + handler.getTimeout() + s);
}
/**
* Returns <code>true</code> if no failures were revealed during the test,
* <code>false</code> otherwise.
*
* @return <code>true</code> if no failures were revealed during the test,
* <code>false</code> otherwise.
*
*/
public boolean getPassedStatus() {
return passed;
}
/**
* Enables memory monitoring.
* <p>
* If notification type of monitoring is chosen, the method adds {@link
* javax.management.NotificationListener
* <code>javax.management.NotificationListener</code>} to enables low
* memory detection support. If monitoring type is polling, a new thread
* that manages the low memory detection is started.
*
* @throws InstanceNotFoundException The MemoryMXBean is not registered on
* the server.
*/
public void enableMonitoring() throws InstanceNotFoundException {
if (isNotification) {
switch (mode) {
case DIRECTLY_MODE:
MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
NotificationEmitter emitter = (NotificationEmitter) mbean;
emitter.addNotificationListener(this, this, null);
break;
case SERVER_MODE:
case PROXY_MODE:
getMBeanServer().addNotificationListener(mbeanObjectName,
this, this, null);
break;
default:
throw new TestBug("Unknown testMode " + mode);
}
} else {
// Polling
// Start a thread that will manage all test modes
polling.start();
}
} // enableMonitoring()
/**
* Disables memory monitoring.
* <p>
* If monitoring type is polling, the thread that manages the low memory
* detection is stopped.
*/
public void disableMonitoring() {
if (!isNotification) {
// Stop polling thread
polling.goOn = false;
}
} // disableMonitoring()
/**
* Updates thresholds. Thresholds values for all pools will be greater
* than <code>used</code> value.
* <p>
* If <code>usage</code> thresholds are chosen, the method updates just
* pools that support usage thresholds. If <code>collection</code>
* thresholds are chosen, the method updates memory pools that support
* collection usage thresholds.
*
* This method is synchronized because it may be invoked from
* <code>handleNotification</code> which is potentially done from
* multiple threads.
*/
public synchronized void updateThresholds() {
if (isUsageThreshold) {
updateUsageThresholds();
} else {
updateCollectionThresholds();
}
}
/**
* Reset thresholds. Thresholds values for all pools will be 1.
* If <code>usage</code> thresholds are chosen, the method updates just
* pools that support usage thresholds. If <code>collection</code>
* thresholds are chosen, the method updates memory pools that support
* collection usage thresholds.
*
* This method is synchronized because it may be invoked from
* multiple threads.
*/
public synchronized void resetThresholds(MemoryType type) {
List pools = getMemoryPoolMBeans();
for (int i = 0; i < pools.size(); i++) {
Object pool = pools.get(i);
if (isUsageThresholdSupported(pool)) {
if (getType(pool).equals(type)) {
setUsageThreshold(pool, 1);
}
}
}
}
/**
* The method is invoked before sending the notification to the listener.
*
* @param notification The notification to be sent.
* @return <i>true</i> if the notification has to be sent to the listener;
* <i>false</i> otherwise.
*
* @see javax.management.NotificationFilter
*/
public boolean isNotificationEnabled(Notification notification) {
String type = notification.getType();
String usage = MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED;
String collection = MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED;
if (isUsageThreshold) {
return type.equals(usage);
} else {
return type.equals(collection);
}
} // isNotificationEnabled()
/**
* The method is invoked when a JMX notification occurs.
*
* @param notification The notification to be sent.
* @param handback An opaque object which helps the listener to associate
* information regarding the MBean emitter.
* @see javax.management.NotificationListener
*/
public void handleNotification(Notification notification, Object handback) {
CompositeData data = (CompositeData) notification.getUserData();
MemoryNotificationInfo mn = MemoryNotificationInfo.from(data);
display(mn.getCount() + " notification \"" + notification.getMessage()
+ "\" is caught on " + (new Date(notification.getTimeStamp()))
+ " by " + mn.getPoolName() + " (" + mn.getUsage() + ")");
updateThresholds();
} // handleNotification()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#resetPeakUsage
* <code>MemoryPoolMXBean.resetPeakUsage()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
*/
public void resetPeakUsage(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
directPool.resetPeakUsage();
break;
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
try {
getMBeanServer().invoke(serverPool, POOL_RESET_PEAK,
null, null);
} catch (Exception e) {
e.printStackTrace(logger.getOutStream());
throw new Failure(e);
}
break;
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
proxyPool.resetPeakUsage();
break;
default:
throw new TestBug("Unknown testMode " + mode);
}
} // resetPeakUsage()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#getPeakUsage
* <code>MemoryPoolMXBean.getPeakUsage()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return a <code>MemoryUsage</code> object representing the peak memory
* usage; <code>null</code> otherwise.
*/
public MemoryUsage getPeakUsage(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.getPeakUsage();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return getMemoryUsageAttribute(serverPool, POOL_PEAK);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.getPeakUsage();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // getPeakUsage()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#getUsage
* <code>MemoryPoolMXBean.getUsage()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return a <code>MemoryUsage</code> object; or <code>null</code> if this
* pool not valid.
*/
public MemoryUsage getUsage(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.getUsage();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return getUsageOnServer(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.getUsage();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // getUsage()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#getCollectionUsage
* <code>MemoryPoolMXBean.getCollectionUsage()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return a <code>MemoryUsage</code> object; or <code>null</code> if this
* method is not supported.
*/
public MemoryUsage getCollectionUsage(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.getCollectionUsage();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return getCollectionUsageOnServer(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.getCollectionUsage();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // getCollectionUsage()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#isValid
* <code>MemoryPoolMXBean.isValid()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return a <code>true</code> if the memory pool is valid in the running
* JVM; <code>null</code> otherwise.
*/
public boolean isValid(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.isValid();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return getBooleanAttribute(serverPool, POOL_VALID);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.isValid();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // isValid()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#isUsageThresholdSupported
* <code>MemoryPoolMXBean.isUsageThresholdSupported()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return a <code>true</code> if the memory pool supports usage threshold;
* <code>null</code> otherwise.
*/
public boolean isUsageThresholdSupported(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.isUsageThresholdSupported();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return isUsageThresholdSupportedOnServer(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.isUsageThresholdSupported();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // isUsageThresholdSupported()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#isCollectionUsageThresholdSupported
* <code>MemoryPoolMXBean.isCollectionUsageThresholdSupported()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return a <code>true</code> if the memory pool supports collection
* usage threshold; <code>null</code> otherwise.
*/
public boolean isCollectionThresholdSupported(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.isCollectionUsageThresholdSupported();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return isCollectionThresholdSupportedOnServer(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.isCollectionUsageThresholdSupported();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // isCollectionThresholdSupported()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#isUsageThresholdExceeded
* <code>MemoryPoolMXBean.isUsageThresholdExceeded()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return a <code>true</code> if the memory usage of this pool reaches or
* exceeds the threshold value; <code>null</code> otherwise.
*/
public boolean isUsageThresholdExceeded(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.isUsageThresholdExceeded();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return isUsageThresholdExceededOnServer(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.isUsageThresholdExceeded();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // isUsageThresholdExceeded()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#isCollectionUsageThresholdExceeded
* <code>MemoryPoolMXBean.isCollectionUsageThresholdExceeded()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return a <code>true</code> if the memory usage of this pool reaches or
* exceeds the collection usage threshold value in the most recent
* collection; <code>null</code> otherwise.
*/
public boolean isCollectionThresholdExceeded(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.isCollectionUsageThresholdExceeded();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return isCollectionThresholdExceededOnServer(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.isCollectionUsageThresholdExceeded();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // isCollectionThresholdExceeded()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#getUsageThreshold
* <code>MemoryPoolMXBean.getUsageThreshold()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return the usage threshold value of this memory pool in bytes.
*/
public long getUsageThreshold(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.getUsageThreshold();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return getUsageThresholdOnServer(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.getUsageThreshold();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // getUsageThreshold()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#getCollectionUsageThreshold
* <code>MemoryPoolMXBean.getCollectionUsageThreshold()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return the collection usage threshold value of this memory pool in
* bytes.
*/
public long getCollectionThreshold(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.getCollectionUsageThreshold();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return getCollectionThresholdOnServer(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.getCollectionUsageThreshold();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // getCollectionThreshold()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#getUsageThresholdCount
* <code>MemoryPoolMXBean.getUsageThresholdCount()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return number of times that the memory usage has crossed its usage
* threshold value.
*/
public long getUsageThresholdCount(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.getUsageThresholdCount();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return getUsageThresholdCountOnServer(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.getUsageThresholdCount();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // getUsageThresholdCount()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#getCollectionUsageThresholdCount
* <code>MemoryPoolMXBean.getCollectionUsageThresholdCount()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return number of times that the memory usage has crossed its collection
* usage threshold value.
*/
public long getCollectionThresholdCount(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.getCollectionUsageThresholdCount();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return getCollectionThresholdCountOnServer(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.getCollectionUsageThresholdCount();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // getCollectionThresholdCount()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#setUsageThreshold
* <code>MemoryPoolMXBean.setUsageThreshold()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @param threshold the new threshold value.
*/
public void setUsageThreshold(Object poolObject, long threshold) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
directPool.setUsageThreshold(threshold);
break;
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
setUsageThresholdOnServer(serverPool, threshold);
break;
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
proxyPool.setUsageThreshold(threshold);
break;
default:
throw new TestBug("Unknown testMode " + mode);
}
} // setUsageThreshold()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#setCollectionUsageThreshold
* <code>MemoryPoolMXBean.setCollectionUsageThreshold()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @param threshold the new collection usage threshold value.
*/
public void setCollectionThreshold(Object poolObject, long threshold) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
directPool.setCollectionUsageThreshold(threshold);
break;
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
setCollectionThresholdOnServer(serverPool, threshold);
break;
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
proxyPool.setCollectionUsageThreshold(threshold);
break;
default:
throw new TestBug("Unknown testMode " + mode);
}
} // setCollectionThreshold()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#getName
* <code>MemoryPoolMXBean.getName()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return the name of the memory pool.
*/
public String getName(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.getName();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return serverPool.toString();
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.getName();
default:
throw new TestBug("Unknown testMode " + mode);
}
} // getName()
/**
* Redirects the invocation to {@link
* java.lang.management.MemoryPoolMXBean#getType
* <code>MemoryPoolMXBean.getType()</code>}.
*
* @param poolObject reference to the pool. The pool may be specified
* either by <code>ObjectName</code>, or
* <code>MemoryPoolMXBean</code>.
* @return the name of the memory pool.
*/
public MemoryType getType(Object poolObject) {
switch (mode) {
case DIRECTLY_MODE:
MemoryPoolMXBean directPool = (MemoryPoolMXBean) poolObject;
return directPool.getType();
case SERVER_MODE:
ObjectName serverPool = (ObjectName) poolObject;
return getType(serverPool);
case PROXY_MODE:
MemoryPoolMXBean proxyPool = (MemoryPoolMXBean) poolObject;
return proxyPool.getType();
default:
throw new TestBug("Unknown testMode " + mode);
}
}
/**
* Redirects the invocation to {@link
* java.lang.management.ManagementFactory#getMemoryPoolMXBeans
* <code>ManagementFactory.getMemoryPoolMXBeans()</code>}.
*
* @return a list of <code>MemoryPoolMXBean</code> objects.
*/
public List<? extends Object> getMemoryPoolMBeans() {
switch (mode) {
case DIRECTLY_MODE:
return ManagementFactory.getMemoryPoolMXBeans();
case SERVER_MODE: {
ObjectName[] names = getMemoryPoolMXBeansOnServer();
ArrayList<ObjectName> list = new ArrayList<ObjectName>();
for (int i = 0; i < names.length; i++) {
list.add(names[i]);
}
return list;
}
case PROXY_MODE: {
ObjectName[] names = getMemoryPoolMXBeansOnServer();
ArrayList<MemoryPoolMXBean> list = new ArrayList<MemoryPoolMXBean>();
for (int i = 0; i < names.length; i++) {
list.add(getProxy(names[i]));
}
return list;
}
default:
throw new TestBug("Unknown testMode " + mode);
}
} // getMemoryPoolMXBeans()
// **********************************************************************
//
// Private methods
//
// **********************************************************************
private MemoryPoolMXBean getProxy(ObjectName objectName) {
try {
MemoryPoolMXBean proxy = (MemoryPoolMXBean) ManagementFactory.newPlatformMXBeanProxy(
getMBeanServer(),
objectName.toString(),
MemoryPoolMXBean.class);
return proxy;
} catch (Exception e) {
throw new Failure(e);
}
}
// Sets new usage threasholds in all pools that match the tested memory and
// support low memory detetion. A new value will be greater than used value
// for the pool.
private void updateUsageThresholds() {
switch (mode) {
case DIRECTLY_MODE:
// we can use the same code here for direct and proxy modes
case PROXY_MODE:
List poolsMBean = ManagementFactory.getMemoryPoolMXBeans();
for (int i = 0; i < poolsMBean.size(); i++) {
MemoryPoolMXBean pool = (MemoryPoolMXBean) poolsMBean.get(i);
if (!pool.isUsageThresholdSupported()) {
continue;
}
MemoryType mt = pool.getType();
if ((!mt.equals(MemoryType.HEAP)
|| !memory.equals(HEAP_TYPE))
&& (!mt.equals(MemoryType.NON_HEAP)
|| !memory.equals(NONHEAP_TYPE))
&& !memory.equals(MIXED_TYPE)) {
continue;
}
// Yes! We got the pool that
// 1. supports usage threshold
// 2. has type that match tested type
// So, update the pool with new threshold
long oldT = pool.getUsageThreshold();
MemoryUsage usage = pool.getUsage();
long newT = newThreshold(usage, oldT, pool.getName());
try {
pool.setUsageThreshold(newT);
} catch (IllegalArgumentException e) {
/*
* Max value might have changed since the call to newThreshold()
* above. If it has fallen below the value of newT, which is certainly
* possible, an exception like this one will be thrown from
* sun.management.MemoryPoolImpl.setUsageThreshold():
*
* java.lang.IllegalArgumentException: Invalid threshold: 48332800 > max (47251456).
*
* We don't know the max value at the time of the failed call, and it
* might have changed since the call once more. So there is no point
* trying to detect whether the IllegalArgumentException had been
* justified, we cannot know it at this point.
*
* The best we can do is log the fact and continue.
*/
displayInfo("setUsageThreshold() failed with " + e + ", ignoring... ",
pool,
"current usage after the call to setUsageThreshold(): ", getUsage(pool),
"threshold: ", newT);
continue;
}
displayInfo("Usage threshold is set", pool, "usage: ", pool.getUsage(), "threshold: ", pool.getUsageThreshold());
if (pool.getUsageThreshold() != newT) {
complain("Cannot reset usage threshold from " + oldT
+ " to " + newT + " in pool " + pool.getName() + " "
+ pool.getUsageThreshold());
passed = false;
}
} // for i
break;
case SERVER_MODE:
ObjectName[] pools = getMemoryPoolMXBeansOnServer();
for (int i = 0; i < pools.length; i++) {
if (!isUsageThresholdSupportedOnServer(pools[i])) {
continue;
}
MemoryType mt = getType(pools[i]);
if ((!mt.equals(MemoryType.HEAP)
|| !memory.equals(HEAP_TYPE))
&& (!mt.equals(MemoryType.NON_HEAP)
|| !memory.equals(NONHEAP_TYPE))
&& !memory.equals(MIXED_TYPE)) {
continue;
}
// Yes! We got the pool that
// 1. supports usage threshold
// 2. has type that match tested type
// So, update the pool with new threshold
long oldT = getUsageThreshold(pools[i]);
long newT = newThreshold(getUsageOnServer(pools[i]), oldT,
pools[i].toString());
try {
setUsageThresholdOnServer(pools[i], newT);
} catch (Failure e) {
/*
* Max value might have changed since the call to newThreshold()
* above. If it has fallen below the value of newT, which is certainly
* possible, an exception like this one will be thrown from
* sun.management.MemoryPoolImpl.setUsageThreshold():
*
* java.lang.IllegalArgumentException: Invalid threshold: 48332800 > max (47251456).
*
* and we'll catch Failure here as a result (it'll be thrown by
* Monitor.setLongAttribute).
*
* We don't know the max value at the time of the failed call, and it
* might have changed since the call once more. So there is no point
* trying to detect whether the IllegalArgumentException had been
* justified, we cannot know it at this point.
*
* The best we can do is log the fact and continue.
*/
displayInfo("setUsageThresholdOnServer() failed with " + e + ", ignoring... ",
pools[i],
"current usage after the call to setUsageThresholdOnServer(): ", getUsageOnServer(pools[i]),
"threshold: ", newT);
continue;
}
displayInfo("Usage threshold is set", null, "pool: ", pools[i], "usage:", getUsageOnServer(pools[i]));
if (getUsageThreshold(pools[i]) != newT) {
complain("Cannot reset usage threshold from " + oldT + " to "
+ newT + " in pool " + pools[i].toString());
passed = false;
}
} // for i
break;
default:
throw new TestBug("Unknown testMode " + mode);
}
} // updateUsageThresholds()
// Sets new collection usage threasholds in all pools that match the tested
// memory and support low memory detetion. A new value will be greater than
// used value for the pool.
private void updateCollectionThresholds() {
switch (mode) {
case DIRECTLY_MODE:
// we can use the same code here for direct and proxy modes
case PROXY_MODE:
List poolsMBean = ManagementFactory.getMemoryPoolMXBeans();
for (int i = 0; i < poolsMBean.size(); i++) {
MemoryPoolMXBean pool = (MemoryPoolMXBean) poolsMBean.get(i);
if (!pool.isCollectionUsageThresholdSupported()) {
continue;
}
MemoryType mt = pool.getType();
if ((!mt.equals(MemoryType.HEAP)
|| !memory.equals(HEAP_TYPE))
&& (!mt.equals(MemoryType.NON_HEAP)
|| !memory.equals(NONHEAP_TYPE))
&& !memory.equals(MIXED_TYPE)) {
continue;
}
// Yes! We got the pool that
// 1. supports collection threshold
// 2. has type that match tested type
// So, update the pool with new threshold
long oldT = pool.getCollectionUsageThreshold();
MemoryUsage usage = pool.getUsage();
long newT = newThreshold(usage, oldT, pool.getName());
try {
pool.setCollectionUsageThreshold(newT);
} catch (IllegalArgumentException e) {
/*
* Max value might have changed since the call to newThreshold()
* above. If it has fallen below the value of newT, which is certainly
* possible, an exception like this one will be thrown from
* sun.management.MemoryPoolImpl.setCollectionUsageThreshold():
*
* java.lang.IllegalArgumentException: Invalid threshold: 48332800 > max (47251456).
*
* We don't know the max value at the time of the failed call, and it
* might have changed since the call once more. So there is no point
* trying to detect whether the IllegalArgumentException had been
* justified, we cannot know it at this point.
*
* The best we can do is log the fact and continue.
*/
displayInfo("setCollectionUsageThreshold() failed with " + e + ", ignoring... ",
pool,
"current usage after the call to setCollectionUsageThreshold(): ", getUsage(pool),
"threshold: ", newT);
continue;
}
displayInfo("Collection threshold is set", pool, "usage: ", getUsage(pool), "threshold: ", newT);
if (pool.getCollectionUsageThreshold() != newT) {
complain("Cannot reset collection threshold from " + oldT
+ " to " + newT + " in pool " + pool.getName() + " "
+ pool.getCollectionUsageThreshold());
passed = false;
}
} // for i
break;
case SERVER_MODE:
ObjectName[] pools = getMemoryPoolMXBeansOnServer();
for (int i = 0; i < pools.length; i++) {
if (!isCollectionThresholdSupportedOnServer(pools[i])) {
continue;
}
MemoryType mt = getType(pools[i]);
if ((!mt.equals(MemoryType.HEAP)
|| !memory.equals(HEAP_TYPE))
&& (!mt.equals(MemoryType.NON_HEAP)
|| !memory.equals(NONHEAP_TYPE))
&& !memory.equals(MIXED_TYPE)) {
continue;
}
// Yes! We got the pool that
// 1. supports usage threshold
// 2. has type that match tested type
// So, update the pool with new threshold
long oldT = getCollectionThresholdOnServer(pools[i]);
long newT = newThreshold(getUsageOnServer(pools[i]), oldT,
pools[i].toString());
try {
setCollectionThresholdOnServer(pools[i], newT);
} catch (Failure e) {
/*
* Max value might have changed since the call to newThreshold()
* above. If it has fallen below the value of newT, which is certainly
* possible, an exception like this one will be thrown from
* sun.management.MemoryPoolImpl.setCollectionUsageThreshold():
*
* java.lang.IllegalArgumentException: Invalid threshold: 48332800 > max (47251456).
*
* and we'll catch Failure here as a result (it'll be thrown by
* Monitor.setLongAttribute).
*
* We don't know the max value at the time of the failed call, and it
* might have changed since the call once more. So there is no point
* trying to detect whether the IllegalArgumentException had been
* justified, we cannot know it at this point.
*
* The best we can do is log the fact and continue.
*/
displayInfo("setCollectionThresholdOnServer() failed with " + e + ", ignoring... ",
pools[i],
"current usage after the call to setCollectionThresholdOnServer(): ", getUsageOnServer(pools[i]),
"threshold: ", newT);
continue;
}
displayInfo("Collection threshold is set", pools[i], "usage: ", getUsageOnServer(pools[i]), "threshold: ", newT);
if (getCollectionThresholdOnServer(pools[i]) != newT) {
complain("Cannot reset collaction threshold from " + oldT
+ " to " + newT + " in pool " + pools[i].toString());
passed = false;
}
} // for i
break;
default:
throw new TestBug("Unknown testMode " + mode);
}
} // updateCollectionThresholds()
// Calculates a new value of threshold based on MemoryUsage and old value of
// the threshold. New one will be not less than previous one.
private long newThreshold(MemoryUsage mu, long oldT, String poolName) {
long newT = mu.getCommitted() / 2 + mu.getUsed() / 2;
long max = mu.getMax();
if (newT < oldT) {
newT = mu.getCommitted() / 2 + oldT / 2;
}
if ((max > -1) && (newT > max)) {
newT = max;
}
displayInfo("Changing threshold", poolName, null, null, "new threshold: ", newT);
return newT;
}
// **********************************************************************
//
// Methods to work with MBean server in SERVER_MODE
//
// **********************************************************************
// Returns usage threshold value of the pool MBean that is accessed via
// MBeanServer
private long getUsageThresholdOnServer(ObjectName pool) {
return getLongAttribute(pool, UT);
}
// Returns collection threshold value of the pool MBean that is accessed via
// MBeanServer
private long getCollectionThresholdOnServer(ObjectName pool) {
return getLongAttribute(pool, CT);
}
// Sets new usage threshold value for the pool MBean that is accessed via
// MBeanServer
private void setUsageThresholdOnServer(ObjectName pool, long value) {
setLongAttribute(pool, UT, value);
}
// Sets new collection threshold value for the pool MBean that is accessed
// via MBeanServer
private void setCollectionThresholdOnServer(ObjectName pool, long value) {
setLongAttribute(pool, CT, value);
}
// Returns MemoryType of the pool MBean that is accessed via MBeanServer.
private MemoryType getType(ObjectName pool) {
try {
Object value = getMBeanServer().getAttribute(pool, POOL_TYPE);
if (value instanceof MemoryType) {
return (MemoryType) value;
} else if (value instanceof String) {
String name = (String) value;
return MemoryType.valueOf(name);
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace(logger.getOutStream());
throw new Failure(e);
}
}
// Returns MemoryUsage of the pool MBean that is accessed via MBeanServer
private MemoryUsage getUsageOnServer(ObjectName pool) {
return getMemoryUsageAttribute(pool, POOL_U);
}
// Returns collection usage of the pool MBean that is accessed via
// MBeanServer
private MemoryUsage getCollectionUsageOnServer(ObjectName pool) {
return getMemoryUsageAttribute(pool, POOL_CU);
}
// Returns if usage threshold is supported in the pool
private boolean isUsageThresholdSupportedOnServer(ObjectName pool) {
return getBooleanAttribute(pool, UT_SUPPORT);
}
// Returns if collection threshold is supported in the pool
private boolean isCollectionThresholdSupportedOnServer(ObjectName pool) {
return getBooleanAttribute(pool, CT_SUPPORT);
}
// Returns if usage threshold is exceeded in the pool
private boolean isUsageThresholdExceededOnServer(ObjectName pool) {
return getBooleanAttribute(pool, UT_EXCEEDED);
}
// Returns if collection threshold is exceeded in the pool
private boolean isCollectionThresholdExceededOnServer(ObjectName pool) {
return getBooleanAttribute(pool, CT_EXCEEDED);
}
// Returns the usage threshold count of the pool
private long getUsageThresholdCountOnServer(ObjectName pool) {
return getLongAttribute(pool, UT_COUNT);
}
// Returns the collection threshold count of the pool.
private long getCollectionThresholdCountOnServer(ObjectName pool) {
return getLongAttribute(pool, CT_COUNT);
}
private final StringBuffer buffer = new StringBuffer(1000);
/**
* Display information about execution ignoring OOM.
*/
private void displayInfo(String message, Object pool, String message1, Object n1, String message2, long n2) {
try {
buffer.delete(0, buffer.length());
buffer.append(message);
if (pool != null) {
buffer.append(", pool: ");
buffer.append(pool.toString());
}
buffer.append(", ");
buffer.append(message1);
buffer.append(n1);
if (message2 != null) {
buffer.append(", ");
buffer.append(message2);
buffer.append(n2);
}
display(buffer.toString());
} catch (OutOfMemoryError e) {
// Ignore.
}
}
/**
* Display information about execution ignoring OOM.
*/
private void displayInfo(String message, MemoryPoolMXBean pool, String message1, Object n1, String message2, Object n2) {
try {
buffer.delete(0, buffer.length());
buffer.append(message);
if (pool != null) {
buffer.append(", pool: ");
buffer.append(pool.getName());
}
buffer.append(", ");
buffer.append(message1);
buffer.append(n1);
if (message2 != null) {
buffer.append(", ");
buffer.append(message2);
buffer.append(n2);
}
display(buffer.toString());
} catch (OutOfMemoryError e) {
// Ignore.
}
}
// Returns all MemoryPoolMXBeans that are registered on the MBeanServer
private ObjectName[] getMemoryPoolMXBeansOnServer() {
// Get all registered MBeans on the server
ObjectName filterName = null;
try {
filterName = new ObjectName(
ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + ",*");
Set<ObjectName> filteredSet = getMBeanServer().queryNames(filterName, null);
return filteredSet.toArray(new ObjectName[0]);
} catch(Exception e) {
return new ObjectName[0];
}
} // getMemoryPoolMXBeansOnServer()
// **********************************************************************
//
// Class to implement polling mechanism of monitoring
//
// **********************************************************************
class Polling extends Thread {
final static long WAIT_TIME = 100; // Milliseconds
Object object = new Object();
long[] thresholdCounts;
boolean goOn = true;
public void run() {
try {
if (isUsageThreshold) {
pollUsageThresholds();
} else {
pollCollectionThresholds();
}
} catch (Failure e) {
complain("Unexpected " + e + " in Polling thread");
e.printStackTrace(logger.getOutStream());
passed = false;
}
} // run()
private void pollUsageThresholds() {
switch (mode) {
case DIRECTLY_MODE:
// we can use the same code here for direct and proxy modes
case PROXY_MODE:
List poolsMBean = ManagementFactory.getMemoryPoolMXBeans();
// Create an array to store all threshold values
thresholdCounts = new long[poolsMBean.size()];
for (int i = 0; i < thresholdCounts.length; i++) {
thresholdCounts[i] = 0;
}
while (goOn) {
synchronized (object) {
try {
object.wait(WAIT_TIME);
} catch (InterruptedException e) {
// Stop the thread
return;
}
} // synchronized
for (int i = 0; i < poolsMBean.size(); i++) {
MemoryPoolMXBean pool = (MemoryPoolMXBean) poolsMBean.get(i);
MemoryType mt = pool.getType();
if (!pool.isUsageThresholdSupported()) {
continue;
}
if ((!mt.equals(MemoryType.HEAP)
|| !memory.equals(HEAP_TYPE))
&& (!mt.equals(MemoryType.NON_HEAP)
|| !memory.equals(NONHEAP_TYPE))
&& !memory.equals(MIXED_TYPE)) {
continue;
}
boolean exceeded;
// The exception is not documented, but it may be
// erroneously thrown
try {
exceeded = pool.isUsageThresholdExceeded();
} catch (IllegalArgumentException e) {
complain("Unexpected exception while retrieving "
+ "isUsageThresholdExceeded() for pool "
+ pool.getName());
e.printStackTrace(logger.getOutStream());
passed = false;
continue;
}
if (!exceeded
|| pool.getUsageThresholdCount() == thresholdCounts[i]) {
continue;
}
// Yes! We got the pool that
// 1. supports usage threshold
// 2. has type that match tested type
// 3. its threshold is exceeded
// So, update all thresholds
long c = pool.getUsageThresholdCount();
if (c <= thresholdCounts[i]) {
complain("Usage threshold count is not greater "
+ "than previous one: " + c + " < "
+ thresholdCounts[i] + " in pool "
+ pool.getName());
passed = false;
}
thresholdCounts[i] = c;
displayInfo("Crossing is noticed", pool, "usage: ", pool.getUsage(), "count: ", c);
updateThresholds();
} // for i
} // while
break;
case SERVER_MODE:
ObjectName[] pools = getMemoryPoolMXBeansOnServer();
// Create an array to store all threshold values
thresholdCounts = new long[pools.length];
for (int i = 0; i < thresholdCounts.length; i++) {
thresholdCounts[i] = 0;
}
while (goOn) {
synchronized (object) {
try {
object.wait(WAIT_TIME);
} catch (InterruptedException e) {
// Stop the thread
return;
}
} // synchronized
for (int i = 0; i < pools.length; i++) {
MemoryType mt = getType(pools[i]);
if (!isUsageThresholdSupportedOnServer(pools[i])) {
continue;
}
if ((!mt.equals(MemoryType.HEAP)
|| !memory.equals(HEAP_TYPE))
&& (!mt.equals(MemoryType.NON_HEAP)
|| !memory.equals(NONHEAP_TYPE))
&& !memory.equals(MIXED_TYPE)) {
continue;
}
boolean exceeded;
// The exception is not documented, but it may be
// erroneously thrown
try {
exceeded = isUsageThresholdExceededOnServer(pools[i]);
} catch (Failure e) {
complain("Unexpected exception while retrieving "
+ "isUsageThresholdExceeded() for pool "
+ pools[i].toString());
e.printStackTrace(logger.getOutStream());
passed = false;
continue;
}
if (!exceeded
|| getUsageThresholdCount(pools[i]) == thresholdCounts[i]) {
continue;
}
// Yes! We got the pool that
// 1. supports usage threshold
// 2. has type that match tested type
// 3. its threshold is exceeded
// So, update all thresholds
long c = getUsageThresholdCount(pools[i]);
if (c <= thresholdCounts[i]) {
complain("Usage threshold count is not greater "
+ "than previous one: " + c + " < "
+ thresholdCounts[i] + " in pool "
+ pools[i].toString());
passed = false;
}
thresholdCounts[i] = c;
displayInfo("Crossing is noticed", null, "pool: ", pools[i], "usage: ", getUsageOnServer(pools[i]));
updateThresholds();
} // for i
} // while
break;
default:
throw new TestBug("Unknown testMode " + mode);
} // switch
} // pollUsageThresholds()
private void pollCollectionThresholds() {
switch (mode) {
case DIRECTLY_MODE:
// we can use the same code here for direct and proxy modes
case PROXY_MODE:
List poolsMBean = ManagementFactory.getMemoryPoolMXBeans();
// Create an array to store all threshold values
thresholdCounts = new long[poolsMBean.size()];
for (int i = 0; i < thresholdCounts.length; i++) {
thresholdCounts[i] = 0;
}
while (goOn) {
synchronized (object) {
try {
object.wait(WAIT_TIME);
} catch (InterruptedException e) {
// Stop the thread
return;
}
} // synchronized
for (int i = 0; i < poolsMBean.size(); i++) {
MemoryPoolMXBean pool = (MemoryPoolMXBean) poolsMBean.get(i);
MemoryType mt = pool.getType();
if (!pool.isCollectionUsageThresholdSupported()) {
continue;
}
if ((!mt.equals(MemoryType.HEAP)
|| !memory.equals(HEAP_TYPE))
&& (!mt.equals(MemoryType.NON_HEAP)
|| !memory.equals(NONHEAP_TYPE))
&& !memory.equals(MIXED_TYPE)) {
continue;
}
boolean exceeded;
// The exception is not documented, but it may be
// erroneously thrown
try {
exceeded = pool.isCollectionUsageThresholdExceeded();
} catch (IllegalArgumentException e) {
complain("Unexpected exception while retrieving "
+ "isCollectionUsageThresholdExceeded()"
+ " for pool " + pool.getName());
e.printStackTrace(logger.getOutStream());
passed = false;
continue;
}
if (!exceeded
|| pool.getCollectionUsageThresholdCount()
== thresholdCounts[i]) {
continue;
}
// Yes! We got thet pool that
// 1. supports collection usage threshold
// 2. has type that match tested type
// 3. its threshold is exceeded
// So, update all thresholds
long c = pool.getCollectionUsageThresholdCount();
if (c <= thresholdCounts[i]) {
complain("Collection usage threshold count is "
+ "not greater than previous one: " + c
+ " < " + thresholdCounts[i] + " in pool "
+ pool.getName());
passed = false;
}
thresholdCounts[i] = c;
displayInfo("Crossing is noticed", pool, "usage: ", pool.getUsage(), "count: ", c);
updateThresholds();
} // for i
} // while
break;
case SERVER_MODE:
ObjectName[] pools = getMemoryPoolMXBeansOnServer();
// Create an array to store all threshold values
thresholdCounts = new long[pools.length];
for (int i = 0; i < thresholdCounts.length; i++) {
thresholdCounts[i] = 0;
}
while (goOn) {
synchronized (object) {
try {
object.wait(WAIT_TIME);
} catch (InterruptedException e) {
// Stop the thread
return;
}
} // synchronized
for (int i = 0; i < pools.length; i++) {
MemoryType mt = getType(pools[i]);
if (!isCollectionThresholdSupportedOnServer(pools[i])) {
continue;
}
if ((!mt.equals(MemoryType.HEAP)
|| !memory.equals(HEAP_TYPE))
&& (!mt.equals(MemoryType.NON_HEAP)
|| !memory.equals(NONHEAP_TYPE))
&& !memory.equals(MIXED_TYPE)) {
continue;
}
boolean exceeded;
// The exception is not documented, but it may be
// erroneously thrown
try {
exceeded = isCollectionThresholdExceededOnServer(pools[i]);
} catch (Failure e) {
complain("Unexpected exception while retrieving "
+ "isCollectionUsageThresholdExceeded() "
+ "for pool " + pools[i].toString());
e.printStackTrace(logger.getOutStream());
passed = false;
continue;
}
if (!exceeded
|| getCollectionThresholdCountOnServer(pools[i])
== thresholdCounts[i]) {
continue;
}
// Yes! We got thet pool that
// 1. supports collection usage threshold
// 2. has type that match tested type
// 3. its threshold is exceeded
// So, update all thresholds
long c = getCollectionThresholdCountOnServer(pools[i]);
if (c <= thresholdCounts[i]) {
complain("Collection usage threshold count is "
+ "not greater than previous one: " + c
+ " < " + thresholdCounts[i] + " in pool "
+ pools[i].toString());
passed = false;
}
thresholdCounts[i] = c;
displayInfo("Crossing is noticed", pools[i], "usage: ", getUsageOnServer(pools[i]), "count: ", c);
updateThresholds();
} // for i
} // while
break;
default:
throw new TestBug("Unknown testMode " + mode);
} // switch
} // pollCollectionThresholds()
} // class Polling
} // MemoryMonitor