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.*;
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 final Sensor usageSensor;
private final 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");
}
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() {
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) {
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) {
resetPeakUsage0();
}
}
public boolean isUsageThresholdExceeded() {
if (!isUsageThresholdSupported()) {
throw new UnsupportedOperationException(
"Usage threshold is not supported");
}
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) {
gcSensorRegistered = true;
setPoolCollectionSensor(gcSensor);
}
setCollectionThreshold0(collectionThreshold, newThreshold);
this.collectionThreshold = newThreshold;
}
}
public boolean isCollectionUsageThresholdExceeded() {
if (!isCollectionUsageThresholdSupported()) {
throw new UnsupportedOperationException(
"CollectionUsage threshold is not supported");
}
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;
}
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);
class PoolSensor extends Sensor {
final MemoryPoolImpl pool;
PoolSensor(MemoryPoolImpl pool, String name) {
super(name);
this.pool = pool;
}
void triggerAction(MemoryUsage usage) {
MemoryImpl.createNotification(MEMORY_THRESHOLD_EXCEEDED,
pool.getName(),
usage,
getCount());
}
void triggerAction() {
}
void clearAction() {
}
}
class CollectionSensor extends Sensor {
final 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() {
}
void clearAction() {
}
}
public ObjectName getObjectName() {
return Util.newObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE, getName());
}
}