Path: blob/master/src/java.management/share/classes/sun/management/MemoryPoolImpl.java
41152 views
/*1* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.management;2627import java.lang.management.ManagementFactory;28import java.lang.management.MemoryPoolMXBean;29import java.lang.management.MemoryUsage;30import java.lang.management.MemoryType;31import java.lang.management.MemoryManagerMXBean;32import javax.management.openmbean.CompositeData;33import javax.management.ObjectName;3435import static java.lang.management.MemoryNotificationInfo.*;3637/**38* Implementation class for a memory pool.39* Standard and committed hotspot-specific metrics if any.40*41* ManagementFactory.getMemoryPoolMXBeans() returns a list of42* instances of this class.43*/44class MemoryPoolImpl implements MemoryPoolMXBean {4546private final String name;47private final boolean isHeap;48private final boolean isValid;49private final boolean collectionThresholdSupported;50private final boolean usageThresholdSupported;5152private MemoryManagerMXBean[] managers;5354private long usageThreshold;55private long collectionThreshold;5657private boolean usageSensorRegistered; // VM-initialized to false58private boolean gcSensorRegistered; // VM-initialized to false59private final Sensor usageSensor;60private final Sensor gcSensor;6162MemoryPoolImpl(String name, boolean isHeap, long usageThreshold,63long gcThreshold) {64this.name = name;65this.isHeap = isHeap;66this.isValid = true;67this.managers = null;68this.usageThreshold = usageThreshold;69this.collectionThreshold = gcThreshold;70this.usageThresholdSupported = (usageThreshold >= 0);71this.collectionThresholdSupported = (gcThreshold >= 0);72this.usageSensor = new PoolSensor(this, name + " usage sensor");73this.gcSensor = new CollectionSensor(this, name + " collection sensor");74}7576public String getName() {77return name;78}7980public boolean isValid() {81return isValid;82}8384public MemoryType getType() {85if (isHeap) {86return MemoryType.HEAP;87} else {88return MemoryType.NON_HEAP;89}90}9192public MemoryUsage getUsage() {93return getUsage0();94}9596public synchronized MemoryUsage getPeakUsage() {97// synchronized since resetPeakUsage may be resetting the peak usage98return getPeakUsage0();99}100101public synchronized long getUsageThreshold() {102if (!isUsageThresholdSupported()) {103throw new UnsupportedOperationException(104"Usage threshold is not supported");105}106return usageThreshold;107}108109public void setUsageThreshold(long newThreshold) {110if (!isUsageThresholdSupported()) {111throw new UnsupportedOperationException(112"Usage threshold is not supported");113}114115Util.checkControlAccess();116117MemoryUsage usage = getUsage0();118if (newThreshold < 0) {119throw new IllegalArgumentException(120"Invalid threshold: " + newThreshold);121}122123if (usage.getMax() != -1 && newThreshold > usage.getMax()) {124throw new IllegalArgumentException(125"Invalid threshold: " + newThreshold +126" must be <= maxSize." +127" Committed = " + usage.getCommitted() +128" Max = " + usage.getMax());129}130131synchronized (this) {132if (!usageSensorRegistered) {133// pass the sensor to VM to begin monitoring134usageSensorRegistered = true;135setPoolUsageSensor(usageSensor);136}137setUsageThreshold0(usageThreshold, newThreshold);138this.usageThreshold = newThreshold;139}140}141142private synchronized MemoryManagerMXBean[] getMemoryManagers() {143if (managers == null) {144managers = getMemoryManagers0();145}146return managers;147}148149public String[] getMemoryManagerNames() {150MemoryManagerMXBean[] mgrs = getMemoryManagers();151152String[] names = new String[mgrs.length];153for (int i = 0; i < mgrs.length; i++) {154names[i] = mgrs[i].getName();155}156return names;157}158159public void resetPeakUsage() {160Util.checkControlAccess();161162synchronized (this) {163// synchronized since getPeakUsage may be called concurrently164resetPeakUsage0();165}166}167168public boolean isUsageThresholdExceeded() {169if (!isUsageThresholdSupported()) {170throw new UnsupportedOperationException(171"Usage threshold is not supported");172}173174// return false if usage threshold crossing checking is disabled175if (usageThreshold == 0) {176return false;177}178179MemoryUsage u = getUsage0();180return (u.getUsed() >= usageThreshold ||181usageSensor.isOn());182}183184public long getUsageThresholdCount() {185if (!isUsageThresholdSupported()) {186throw new UnsupportedOperationException(187"Usage threshold is not supported");188}189190return usageSensor.getCount();191}192193public boolean isUsageThresholdSupported() {194return usageThresholdSupported;195}196197public synchronized long getCollectionUsageThreshold() {198if (!isCollectionUsageThresholdSupported()) {199throw new UnsupportedOperationException(200"CollectionUsage threshold is not supported");201}202203return collectionThreshold;204}205206public void setCollectionUsageThreshold(long newThreshold) {207if (!isCollectionUsageThresholdSupported()) {208throw new UnsupportedOperationException(209"CollectionUsage threshold is not supported");210}211212Util.checkControlAccess();213214MemoryUsage usage = getUsage0();215if (newThreshold < 0) {216throw new IllegalArgumentException(217"Invalid threshold: " + newThreshold);218}219220if (usage.getMax() != -1 && newThreshold > usage.getMax()) {221throw new IllegalArgumentException(222"Invalid threshold: " + newThreshold +223" > max (" + usage.getMax() + ").");224}225226synchronized (this) {227if (!gcSensorRegistered) {228// pass the sensor to VM to begin monitoring229gcSensorRegistered = true;230setPoolCollectionSensor(gcSensor);231}232setCollectionThreshold0(collectionThreshold, newThreshold);233this.collectionThreshold = newThreshold;234}235}236237public boolean isCollectionUsageThresholdExceeded() {238if (!isCollectionUsageThresholdSupported()) {239throw new UnsupportedOperationException(240"CollectionUsage threshold is not supported");241}242243// return false if usage threshold crossing checking is disabled244if (collectionThreshold == 0) {245return false;246}247248MemoryUsage u = getCollectionUsage0();249return (gcSensor.isOn() ||250(u != null && u.getUsed() >= collectionThreshold));251}252253public long getCollectionUsageThresholdCount() {254if (!isCollectionUsageThresholdSupported()) {255throw new UnsupportedOperationException(256"CollectionUsage threshold is not supported");257}258259return gcSensor.getCount();260}261262public MemoryUsage getCollectionUsage() {263return getCollectionUsage0();264}265266public boolean isCollectionUsageThresholdSupported() {267return collectionThresholdSupported;268}269270// Native VM support271private native MemoryUsage getUsage0();272private native MemoryUsage getPeakUsage0();273private native MemoryUsage getCollectionUsage0();274private native void setUsageThreshold0(long current, long newThreshold);275private native void setCollectionThreshold0(long current, long newThreshold);276private native void resetPeakUsage0();277private native MemoryManagerMXBean[] getMemoryManagers0();278private native void setPoolUsageSensor(Sensor s);279private native void setPoolCollectionSensor(Sensor s);280281// package private282283/**284* PoolSensor will be triggered by the VM when the memory285* usage of a memory pool is crossing the usage threshold.286* The VM will not trigger this sensor in subsequent crossing287* unless the memory usage has returned below the threshold.288*/289class PoolSensor extends Sensor {290final MemoryPoolImpl pool;291292PoolSensor(MemoryPoolImpl pool, String name) {293super(name);294this.pool = pool;295}296void triggerAction(MemoryUsage usage) {297// create and send notification298MemoryImpl.createNotification(MEMORY_THRESHOLD_EXCEEDED,299pool.getName(),300usage,301getCount());302}303void triggerAction() {304// do nothing305}306void clearAction() {307// do nothing308}309}310311/**312* CollectionSensor will be triggered and cleared by the VM313* when the memory usage of a memory pool after GC is crossing314* the collection threshold.315* The VM will trigger this sensor in subsequent crossing316* regardless if the memory usage has changed since the previous GC.317*/318class CollectionSensor extends Sensor {319final MemoryPoolImpl pool;320CollectionSensor(MemoryPoolImpl pool, String name) {321super(name);322this.pool = pool;323}324void triggerAction(MemoryUsage usage) {325MemoryImpl.createNotification(MEMORY_COLLECTION_THRESHOLD_EXCEEDED,326pool.getName(),327usage,328gcSensor.getCount());329}330void triggerAction() {331// do nothing332}333void clearAction() {334// do nothing335}336}337338public ObjectName getObjectName() {339return Util.newObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE, getName());340}341342}343344345