/* * Copyright (c) 2003, 2008, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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 sun.management;import java.lang.management.ManagementFactory;import java.lang.management.MemoryPoolMXBean;import java.lang.management.MemoryUsage;import java.lang.management.MemoryType;import java.lang.management.MemoryManagerMXBean;import javax.management.openmbean.CompositeData;import javax.management.ObjectName;import static java.lang.management.MemoryNotificationInfo.*;/** * Implementation class for a memory pool. * Standard and committed hotspot-specific metrics if any. * * ManagementFactory.getMemoryPoolMXBeans() returns a list of * instances of this class. */class MemoryPoolImpl implements MemoryPoolMXBean { private final String name; private final boolean isHeap; private final boolean isValid; private final boolean collectionThresholdSupported; private final boolean usageThresholdSupported; private MemoryManagerMXBean[] managers; private long usageThreshold; private long collectionThreshold; private boolean usageSensorRegistered; private boolean gcSensorRegistered; private Sensor usageSensor; private Sensor gcSensor; MemoryPoolImpl(String name, boolean isHeap, long usageThreshold, long gcThreshold) { this.name = name; this.isHeap = isHeap; this.isValid = true; this.managers = null; this.usageThreshold = usageThreshold; this.collectionThreshold = gcThreshold; this.usageThresholdSupported = (usageThreshold >= 0); this.collectionThresholdSupported = (gcThreshold >= 0); this.usageSensor = new PoolSensor(this, name + " usage sensor"); this.gcSensor = new CollectionSensor(this, name + " collection sensor"); this.usageSensorRegistered = false; this.gcSensorRegistered = false; } public String getName() { return name; } public boolean isValid() { return isValid; } public MemoryType getType() { if (isHeap) { return MemoryType.HEAP; } else { return MemoryType.NON_HEAP; } } public MemoryUsage getUsage() { return getUsage0(); } public synchronized MemoryUsage getPeakUsage() { // synchronized since resetPeakUsage may be resetting the peak usage return getPeakUsage0(); } public synchronized long getUsageThreshold() { if (!isUsageThresholdSupported()) { throw new UnsupportedOperationException( "Usage threshold is not supported"); } return usageThreshold; } public void setUsageThreshold(long newThreshold) { if (!isUsageThresholdSupported()) { throw new UnsupportedOperationException( "Usage threshold is not supported"); } Util.checkControlAccess(); MemoryUsage usage = getUsage0(); if (newThreshold < 0) { throw new IllegalArgumentException( "Invalid threshold: " + newThreshold); } if (usage.getMax() != -1 && newThreshold > usage.getMax()) { throw new IllegalArgumentException( "Invalid threshold: " + newThreshold + " must be <= maxSize." + " Committed = " + usage.getCommitted() + " Max = " + usage.getMax()); } synchronized (this) { if (!usageSensorRegistered) { // pass the sensor to VM to begin monitoring usageSensorRegistered = true; setPoolUsageSensor(usageSensor); } setUsageThreshold0(usageThreshold, newThreshold); this.usageThreshold = newThreshold; } } private synchronized MemoryManagerMXBean[] getMemoryManagers() { if (managers == null) { managers = getMemoryManagers0(); } return managers; } public String[] getMemoryManagerNames() { MemoryManagerMXBean[] mgrs = getMemoryManagers(); String[] names = new String[mgrs.length]; for (int i = 0; i < mgrs.length; i++) { names[i] = mgrs[i].getName(); } return names; } public void resetPeakUsage() { Util.checkControlAccess(); synchronized (this) { // synchronized since getPeakUsage may be called concurrently resetPeakUsage0(); } } public boolean isUsageThresholdExceeded() { if (!isUsageThresholdSupported()) { throw new UnsupportedOperationException( "Usage threshold is not supported"); } // return false if usage threshold crossing checking is disabled if (usageThreshold == 0) { return false; } MemoryUsage u = getUsage0(); return (u.getUsed() >= usageThreshold || usageSensor.isOn()); } public long getUsageThresholdCount() { if (!isUsageThresholdSupported()) { throw new UnsupportedOperationException( "Usage threshold is not supported"); } return usageSensor.getCount(); } public boolean isUsageThresholdSupported() { return usageThresholdSupported; } public synchronized long getCollectionUsageThreshold() { if (!isCollectionUsageThresholdSupported()) { throw new UnsupportedOperationException( "CollectionUsage threshold is not supported"); } return collectionThreshold; } public void setCollectionUsageThreshold(long newThreshold) { if (!isCollectionUsageThresholdSupported()) { throw new UnsupportedOperationException( "CollectionUsage threshold is not supported"); } Util.checkControlAccess(); MemoryUsage usage = getUsage0(); if (newThreshold < 0) { throw new IllegalArgumentException( "Invalid threshold: " + newThreshold); } if (usage.getMax() != -1 && newThreshold > usage.getMax()) { throw new IllegalArgumentException( "Invalid threshold: " + newThreshold + " > max (" + usage.getMax() + ")."); } synchronized (this) { if (!gcSensorRegistered) { // pass the sensor to VM to begin monitoring gcSensorRegistered = true; setPoolCollectionSensor(gcSensor); } setCollectionThreshold0(collectionThreshold, newThreshold); this.collectionThreshold = newThreshold; } } public boolean isCollectionUsageThresholdExceeded() { if (!isCollectionUsageThresholdSupported()) { throw new UnsupportedOperationException( "CollectionUsage threshold is not supported"); } // return false if usage threshold crossing checking is disabled if (collectionThreshold == 0) { return false; } MemoryUsage u = getCollectionUsage0(); return (gcSensor.isOn() || (u != null && u.getUsed() >= collectionThreshold)); } public long getCollectionUsageThresholdCount() { if (!isCollectionUsageThresholdSupported()) { throw new UnsupportedOperationException( "CollectionUsage threshold is not supported"); } return gcSensor.getCount(); } public MemoryUsage getCollectionUsage() { return getCollectionUsage0(); } public boolean isCollectionUsageThresholdSupported() { return collectionThresholdSupported; } // Native VM support private native MemoryUsage getUsage0(); private native MemoryUsage getPeakUsage0(); private native MemoryUsage getCollectionUsage0(); private native void setUsageThreshold0(long current, long newThreshold); private native void setCollectionThreshold0(long current, long newThreshold); private native void resetPeakUsage0(); private native MemoryManagerMXBean[] getMemoryManagers0(); private native void setPoolUsageSensor(Sensor s); private native void setPoolCollectionSensor(Sensor s); // package private /** * PoolSensor will be triggered by the VM when the memory * usage of a memory pool is crossing the usage threshold. * The VM will not trigger this sensor in subsequent crossing * unless the memory usage has returned below the threshold. */ class PoolSensor extends Sensor { MemoryPoolImpl pool; PoolSensor(MemoryPoolImpl pool, String name) { super(name); this.pool = pool; } void triggerAction(MemoryUsage usage) { // create and send notification MemoryImpl.createNotification(MEMORY_THRESHOLD_EXCEEDED, pool.getName(), usage, getCount()); } void triggerAction() { // Should not reach here throw new AssertionError("Should not reach here"); } void clearAction() { // do nothing } } /** * CollectionSensor will be triggered and cleared by the VM * when the memory usage of a memory pool after GC is crossing * the collection threshold. * The VM will trigger this sensor in subsequent crossing * regardless if the memory usage has changed siince the previous GC. */ class CollectionSensor extends Sensor { MemoryPoolImpl pool; CollectionSensor(MemoryPoolImpl pool, String name) { super(name); this.pool = pool; } void triggerAction(MemoryUsage usage) { MemoryImpl.createNotification(MEMORY_COLLECTION_THRESHOLD_EXCEEDED, pool.getName(), usage, gcSensor.getCount()); } void triggerAction() { // Should not reach here throw new AssertionError("Should not reach here"); } void clearAction() { // do nothing } } public ObjectName getObjectName() { return Util.newObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE, getName()); }}
/*
* Copyright (c) 2003, 2008, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 sun.management;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.MemoryType;
import java.lang.management.MemoryManagerMXBean;
import javax.management.openmbean.CompositeData;
import javax.management.ObjectName;
import static java.lang.management.MemoryNotificationInfo.*;
/**
* Implementation class for a memory pool.
* Standard and committed hotspot-specific metrics if any.
*
* ManagementFactory.getMemoryPoolMXBeans() returns a list of
* instances of this class.
*/
class MemoryPoolImpl implements MemoryPoolMXBean {
private final String name;
private final boolean isHeap;
private final boolean isValid;
private final boolean collectionThresholdSupported;
private final boolean usageThresholdSupported;
private MemoryManagerMXBean[] managers;
private long usageThreshold;
private long collectionThreshold;
private boolean usageSensorRegistered;
private boolean gcSensorRegistered;
private Sensor usageSensor;
private Sensor gcSensor;
MemoryPoolImpl(String name, boolean isHeap, long usageThreshold,
long gcThreshold) {
this.name = name;
this.isHeap = isHeap;
this.isValid = true;
this.managers = null;
this.usageThreshold = usageThreshold;
this.collectionThreshold = gcThreshold;
this.usageThresholdSupported = (usageThreshold >= 0);
this.collectionThresholdSupported = (gcThreshold >= 0);
this.usageSensor = new PoolSensor(this, name + " usage sensor");
this.gcSensor = new CollectionSensor(this, name + " collection sensor");
this.usageSensorRegistered = false;
this.gcSensorRegistered = false;
}
public String getName() {
return name;
}
public boolean isValid() {
return isValid;
}
public MemoryType getType() {
if (isHeap) {
return MemoryType.HEAP;
} else {
return MemoryType.NON_HEAP;
}
}
public MemoryUsage getUsage() {
return getUsage0();
}
public synchronized MemoryUsage getPeakUsage() {
// synchronized since resetPeakUsage may be resetting the peak usage
return getPeakUsage0();
}
public synchronized long getUsageThreshold() {
if (!isUsageThresholdSupported()) {
throw new UnsupportedOperationException(
"Usage threshold is not supported");
}
return usageThreshold;
}
public void setUsageThreshold(long newThreshold) {
if (!isUsageThresholdSupported()) {
throw new UnsupportedOperationException(
"Usage threshold is not supported");
}
Util.checkControlAccess();
MemoryUsage usage = getUsage0();
if (newThreshold < 0) {
throw new IllegalArgumentException(
"Invalid threshold: " + newThreshold);
}
if (usage.getMax() != -1 && newThreshold > usage.getMax()) {
throw new IllegalArgumentException(
"Invalid threshold: " + newThreshold +
" must be <= maxSize." +
" Committed = " + usage.getCommitted() +
" Max = " + usage.getMax());
}
synchronized (this) {
if (!usageSensorRegistered) {
// pass the sensor to VM to begin monitoring
usageSensorRegistered = true;
setPoolUsageSensor(usageSensor);
}
setUsageThreshold0(usageThreshold, newThreshold);
this.usageThreshold = newThreshold;
}
}
private synchronized MemoryManagerMXBean[] getMemoryManagers() {
if (managers == null) {
managers = getMemoryManagers0();
}
return managers;
}
public String[] getMemoryManagerNames() {
MemoryManagerMXBean[] mgrs = getMemoryManagers();
String[] names = new String[mgrs.length];
for (int i = 0; i < mgrs.length; i++) {
names[i] = mgrs[i].getName();
}
return names;
}
public void resetPeakUsage() {
Util.checkControlAccess();
synchronized (this) {
// synchronized since getPeakUsage may be called concurrently
resetPeakUsage0();
}
}
public boolean isUsageThresholdExceeded() {
if (!isUsageThresholdSupported()) {
throw new UnsupportedOperationException(
"Usage threshold is not supported");
}
// return false if usage threshold crossing checking is disabled
if (usageThreshold == 0) {
return false;
}
MemoryUsage u = getUsage0();
return (u.getUsed() >= usageThreshold ||
usageSensor.isOn());
}
public long getUsageThresholdCount() {
if (!isUsageThresholdSupported()) {
throw new UnsupportedOperationException(
"Usage threshold is not supported");
}
return usageSensor.getCount();
}
public boolean isUsageThresholdSupported() {
return usageThresholdSupported;
}
public synchronized long getCollectionUsageThreshold() {
if (!isCollectionUsageThresholdSupported()) {
throw new UnsupportedOperationException(
"CollectionUsage threshold is not supported");
}
return collectionThreshold;
}
public void setCollectionUsageThreshold(long newThreshold) {
if (!isCollectionUsageThresholdSupported()) {
throw new UnsupportedOperationException(
"CollectionUsage threshold is not supported");
}
Util.checkControlAccess();
MemoryUsage usage = getUsage0();
if (newThreshold < 0) {
throw new IllegalArgumentException(
"Invalid threshold: " + newThreshold);
}
if (usage.getMax() != -1 && newThreshold > usage.getMax()) {
throw new IllegalArgumentException(
"Invalid threshold: " + newThreshold +
" > max (" + usage.getMax() + ").");
}
synchronized (this) {
if (!gcSensorRegistered) {
// pass the sensor to VM to begin monitoring
gcSensorRegistered = true;
setPoolCollectionSensor(gcSensor);
}
setCollectionThreshold0(collectionThreshold, newThreshold);
this.collectionThreshold = newThreshold;
}
}
public boolean isCollectionUsageThresholdExceeded() {
if (!isCollectionUsageThresholdSupported()) {
throw new UnsupportedOperationException(
"CollectionUsage threshold is not supported");
}
// return false if usage threshold crossing checking is disabled
if (collectionThreshold == 0) {
return false;
}
MemoryUsage u = getCollectionUsage0();
return (gcSensor.isOn() ||
(u != null && u.getUsed() >= collectionThreshold));
}
public long getCollectionUsageThresholdCount() {
if (!isCollectionUsageThresholdSupported()) {
throw new UnsupportedOperationException(
"CollectionUsage threshold is not supported");
}
return gcSensor.getCount();
}
public MemoryUsage getCollectionUsage() {
return getCollectionUsage0();
}
public boolean isCollectionUsageThresholdSupported() {
return collectionThresholdSupported;
}
// Native VM support
private native MemoryUsage getUsage0();
private native MemoryUsage getPeakUsage0();
private native MemoryUsage getCollectionUsage0();
private native void setUsageThreshold0(long current, long newThreshold);
private native void setCollectionThreshold0(long current, long newThreshold);
private native void resetPeakUsage0();
private native MemoryManagerMXBean[] getMemoryManagers0();
private native void setPoolUsageSensor(Sensor s);
private native void setPoolCollectionSensor(Sensor s);
// package private
/**
* PoolSensor will be triggered by the VM when the memory
* usage of a memory pool is crossing the usage threshold.
* The VM will not trigger this sensor in subsequent crossing
* unless the memory usage has returned below the threshold.
*/
class PoolSensor extends Sensor {
MemoryPoolImpl pool;
PoolSensor(MemoryPoolImpl pool, String name) {
super(name);
this.pool = pool;
}
void triggerAction(MemoryUsage usage) {
// create and send notification
MemoryImpl.createNotification(MEMORY_THRESHOLD_EXCEEDED,
pool.getName(),
usage,
getCount());
}
void triggerAction() {
// Should not reach here
throw new AssertionError("Should not reach here");
}
void clearAction() {
// do nothing
}
}
/**
* CollectionSensor will be triggered and cleared by the VM
* when the memory usage of a memory pool after GC is crossing
* the collection threshold.
* The VM will trigger this sensor in subsequent crossing
* regardless if the memory usage has changed siince the previous GC.
*/
class CollectionSensor extends Sensor {
MemoryPoolImpl pool;
CollectionSensor(MemoryPoolImpl pool, String name) {
super(name);
this.pool = pool;
}
void triggerAction(MemoryUsage usage) {
MemoryImpl.createNotification(MEMORY_COLLECTION_THRESHOLD_EXCEEDED,
pool.getName(),
usage,
gcSensor.getCount());
}
void triggerAction() {
// Should not reach here
throw new AssertionError("Should not reach here");
}
void clearAction() {
// do nothing
}
}
public ObjectName getObjectName() {
return Util.newObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE, getName());
}
}