| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
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 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() { | 
 | 
          | 
 | 
        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);  | 
 | 
 | 
 | 
    // package private  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    class PoolSensor extends Sensor { | 
 | 
        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() { | 
 | 
            // do nothing  | 
 | 
        }  | 
 | 
        void clearAction() { | 
 | 
            // do nothing  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    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() { | 
 | 
            // do nothing  | 
 | 
        }  | 
 | 
        void clearAction() { | 
 | 
            // do nothing  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public ObjectName getObjectName() { | 
 | 
        return Util.newObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE, getName());  | 
 | 
    }  | 
 | 
 | 
 | 
}  |