public interface MemoryPoolMXBean extends PlatformManagedObject
memory managers
管理。
Java虚拟机具有此接口的实现类的一个或多个实例。 实现此接口的实例是一个MXBean可以通过调用来获得ManagementFactory.getMemoryPoolMXBeans()
方法或从platform MBeanServer
方法。
该ObjectName用于唯一地识别的MXBean内存池的MBeanServer内是:
java.lang:type=MemoryPool
,name= pool's name
可以通过调用PlatformManagedObject.getObjectName()
方法获得。
Java虚拟机具有用于对象分配的堆,并且还维护方法区域和Java虚拟机执行的非堆内存。 Java虚拟机可以有一个或多个内存池。 每个内存池代表以下类型之一的内存区域:
getUsage()
方法提供了内存池当前使用情况的估计。
对于垃圾回收的内存池,使用的内存量包括池中所有对象占用的内存,包括可访问和不可访问的对象。
一般来说,这种方法是一个轻量级的操作来获得大致的内存使用。 对于一些内存池,例如,当对象不是连续打包时,该方法可能是一个昂贵的操作,需要一些计算来确定当前的内存使用情况。 在这种情况下,实施应该记录。
getPeakUsage()
方法返回,并通过调用resetPeakUsage()
方法重置。
setUsageThreshold
方法设置使用阈值。
如果阈值设置为正值,则在该内存池中启用使用阈值交叉检查。
如果使用阈值设置为零,则禁用此内存池上的使用阈值交叉检查。
isUsageThresholdSupported()
方法可用于确定是否支持此功能。
Java虚拟机在其最佳适当时间(通常在垃圾收集时间)的基础上执行基于内存池的使用阈值交叉检查。 每个内存池维护一个usage threshold count
,每当Java虚拟机检测到内存池使用率正在超过阈值时,它将会增加。
这种可管理的使用阈值属性设计用于以低开销监视内存使用的增长趋势。 某些内存池的使用阈值可能不合适。 例如,一代代垃圾回收器是许多Java虚拟机实现中使用的常见的垃圾收集算法,它根据年龄管理两代或多代隔离对象。 大多数的对象分配在最年轻的一代 (比如一个托儿所记忆库)中。 托儿所内存池被设计为填充并收集托儿所内存池将释放其大部分内存空间,因为它预计主要包含短命的对象,并且大部分在垃圾收集时无法访问。 在这种情况下,更适合于苗圃内存池不支持使用阈值。 另外,如果一个内存池中的对象分配成本非常低(例如,只是原子指针交换),则Java虚拟机可能不支持该内存池的使用阈值,因为将使用率与阈值高于对象分配的成本。
可以使用polling或threshold notification机制来监控系统的内存使用情况。
应用程序可以通过调用所述连续监视其内存使用getUsage()
所有内存池法或isUsageThresholdExceeded()
对于支持使用量阈值的那些存储器池的方法。 以下是具有专用于任务分发和处理的线程的示例代码。 在每隔一段时间,它将根据其内存使用情况确定是否应该接收和处理新任务。 如果内存使用量超过其使用阈值,它会将所有未完成的任务重新分配给其他虚拟机,并停止接收新任务,直到内存使用率低于其使用阈值。
// Assume the usage threshold is supported for this pool.
// Set the threshold to myThreshold above which no new tasks
// should be taken.
pool.setUsageThreshold(myThreshold);
....
boolean lowMemory = false;
while (true) {
if (pool.isUsageThresholdExceeded()) {
// potential low memory, so redistribute tasks to other VMs
lowMemory = true;
redistributeTasks();
// stop receiving new tasks
stopReceivingTasks();
} else {
if (lowMemory) {
// resume receiving tasks
lowMemory = false;
resumeReceivingTasks();
}
// processing outstanding task
...
}
// sleep for sometime
try {
Thread.sleep(sometime);
} catch (InterruptedException e) {
...
}
}
getUsageThresholdCount()
方法返回的使用阈值计数可用于确定两次轮询之间的内存使用情况是否已经低于阈值。 下面显示另一个例子,如果内存池处于低内存下并且在动作处理时间内忽略内存使用情况的变化,则需要采取一些措施。
// Assume the usage threshold is supported for this pool.
// Set the threshold to myThreshold which determines if
// the application will take some action under low memory condition.
pool.setUsageThreshold(myThreshold);
int prevCrossingCount = 0;
while (true) {
// A busy loop to detect when the memory usage
// has exceeded the threshold.
while (!pool.isUsageThresholdExceeded() ||
pool.getUsageThresholdCount() == prevCrossingCount) {
try {
Thread.sleep(sometime)
} catch (InterruptException e) {
....
}
}
// Do some processing such as check for memory usage
// and issue a warning
....
// Gets the current threshold count. The busy loop will then
// ignore any crossing of threshold happens during the processing.
prevCrossingCount = pool.getUsageThresholdCount();
}
MemoryMXBean
将发出使用阈值通知 。 当Java虚拟机检测到内存池的内存使用量达到或超过使用阈值时,虚拟机将触发MemoryMXBean发出usage threshold exceeded notification
。 超出使用阈值超过通知将不会生成,直到使用率已经低于阈值,然后再次超过它。
下面是一个实现与上述第一个例子相同逻辑的示例代码,但使用使用阈值通知机制来检测低内存条件而不是轮询。 在该示例代码中,在接收到通知时,通知侦听器通知另一线程以执行实际动作,例如重新分配未完成的任务,停止接收任务或恢复接收任务。 handleNotification方法应设计为执行极少量的工作,并且无延迟地返回,以避免导致后续通知的延迟。 耗时的操作应该由单独的线程执行。 通知侦听器可以由多个线程同时调用; 所以侦听器执行的任务应该被正确同步。
class MyListener implements javax.management.NotificationListener {
public void handleNotification(Notification notification, Object handback) {
String notifType = notification.getType();
if (notifType.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) {
// potential low memory, notify another thread
// to redistribute outstanding tasks to other VMs
// and stop receiving new tasks.
lowMemory = true;
notifyAnotherThread(lowMemory);
}
}
}
// Register MyListener with MemoryMXBean
MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
NotificationEmitter emitter = (NotificationEmitter) mbean;
MyListener listener = new MyListener();
emitter.addNotificationListener(listener, null, null);
// Assume this pool supports a usage threshold.
// Set the threshold to myThreshold above which no new tasks
// should be taken.
pool.setUsageThreshold(myThreshold);
// Usage threshold detection is enabled and notification will be
// handled by MyListener. Continue for other processing.
....
这是毫无时MemoryMXBean会发出阈值通知当通知将交付的保证。 当调用通知侦听器时,内存池的内存使用量可能会超过使用阈值多次。 MemoryNotificationInfo.getCount()
方法返回在构建通知时内存使用量超过使用阈值的次数。 它可以与getUsageThresholdCount()
方法返回的当前使用阈值进行比较,以确定是否发生了这种情况。
collection usage threshold exceeded notification
将由发射MemoryMXBean
。
此外, collection usage threshold count
将会增加。
isCollectionUsageThresholdSupported()
方法可用于确定是否支持此功能。
Java虚拟机基于内存池执行收集使用阈值检查。 如果集合使用阈值设置为正值,则启用此检查。 如果集合使用阈值设置为零,则此内存池将禁用此检查。 默认值为零。 Java虚拟机在垃圾收集时执行收集使用阈值检查。
一些垃圾回收的内存池可能选择不支持收集使用阈值。 例如,内存池仅由连续的并发垃圾回收器管理。 对象可以通过一些线程在此内存池中分配,而未使用的对象同时由并发垃圾回收器进行回收。 除非有明确的垃圾回收时间是检查内存使用的最佳时间,否则不应该支持收集使用率阈值。
集合使用阈值用于在Java虚拟机花费回收内存空间后,监视内存使用情况。 收集使用情况也可以通过上面针对usage threshold描述的轮询和阈值通知机制进行监控 。
ManagementFactory.getPlatformMXBeans(Class)
,
JMX Specification. ,
Ways to Access MXBeans
Modifier and Type | Method and Description |
---|---|
MemoryUsage |
getCollectionUsage()
返回Java虚拟机最近花费在回收此内存池中未使用对象的努力后的内存使用情况。
|
long |
getCollectionUsageThreshold()
以字节为单位返回此内存池的集合使用阈值。
|
long |
getCollectionUsageThresholdCount()
返回Java虚拟机检测到内存使用量达到或超过集合使用率阈值的次数。
|
String[] |
getMemoryManagerNames()
返回管理此内存池的内存管理器的名称。
|
String |
getName()
返回表示此内存池的名称。
|
MemoryUsage |
getPeakUsage()
从Java虚拟机启动或从峰值重置以来,返回此内存池的高峰内存使用情况。
|
MemoryType |
getType()
返回此内存池的类型。
|
MemoryUsage |
getUsage()
返回此内存池的内存使用情况的估计。
|
long |
getUsageThreshold()
以字节为单位返回此内存池的使用阈值。
|
long |
getUsageThresholdCount()
返回内存使用量超过使用率阈值的次数。
|
boolean |
isCollectionUsageThresholdExceeded()
测试Java虚拟机所耗费的最新集合之后的内存池的内存使用情况是否已达到或超过其集合使用率阈值。
|
boolean |
isCollectionUsageThresholdSupported()
测试此内存池是否支持集合使用阈值。
|
boolean |
isUsageThresholdExceeded()
测试此内存池的内存使用情况是否达到或超过其使用阈值。
|
boolean |
isUsageThresholdSupported()
测试此内存池是否支持使用阈值。
|
boolean |
isValid()
测试此内存池是否在Java虚拟机中有效。
|
void |
resetPeakUsage()
将此内存池的高峰内存使用率统计信息重置为当前内存使用情况。
|
void |
setCollectionUsageThreshold(long threshold)
将此内存池的集合使用
阈值设置为给定的
threshold值。
|
void |
setUsageThreshold(long threshold)
如果此内存池支持使用阈值,则将此内存池的
阈值设置为给定的
threshold值。
|
getObjectName
String getName()
MemoryType getType()
MBeanServer访问 :
的MemoryType映射类型为String和值是MemoryType的名称。
MemoryUsage getUsage()
此方法请求Java虚拟机尽力估计此内存池的当前内存使用情况。 对于一些内存池,该方法可能是一个昂贵的操作,需要一些计算来确定估计。 在这种情况下,实施应该记录。
该方法设计用于监控系统内存使用情况和检测低内存条件。
MBeanServer访问 :
MemoryUsage的映射类型是CompositeData ,其属性在MemoryUsage
中指定 。
MemoryUsage
对象;
或null如果此池无效。
MemoryUsage getPeakUsage()
MBeanServer访问 :
MemoryUsage的映射类型是CompositeData ,其属性在MemoryUsage
中指定 。
MemoryUsage
对象;
或null如果此池无效。
void resetPeakUsage()
SecurityException
- 如果安全管理器存在,并且调用者没有ManagementPermission(“控制”)。
boolean isValid()
String[] getMemoryManagerNames()
long getUsageThreshold()
UnsupportedOperationException
- 如果此内存池不支持使用阈值。
isUsageThresholdSupported()
void setUsageThreshold(long threshold)
threshold
- 新的阈值(以字节为单位)。
必须是非负数。
IllegalArgumentException
- 如果
threshold为负数或大于此内存池的最大内存量(如果已定义)。
UnsupportedOperationException
- 如果此内存池不支持使用阈值。
SecurityException
- 如果安全管理器存在且呼叫者没有ManagementPermission(“控制”)。
isUsageThresholdSupported()
,
Usage threshold
boolean isUsageThresholdExceeded()
UnsupportedOperationException
- 如果此内存池不支持使用阈值。
long getUsageThresholdCount()
UnsupportedOperationException
- 如果此内存池不支持使用阈值。
boolean isUsageThresholdSupported()
long getCollectionUsageThreshold()
UnsupportedOperationException
- 如果此内存池不支持集合使用阈值。
isCollectionUsageThresholdSupported()
void setCollectionUsageThreshold(long threshold)
如果阈值设置为正值,则在此内存池中启用集合使用阈值交叉检查。 如果设置为零,则禁用集合使用阈值交叉检查。
threshold
- 新的集合使用阈值(以字节为单位)。
必须是非负数。
IllegalArgumentException
- 如果
threshold为负数或大于此内存池的最大内存量(如果已定义)。
UnsupportedOperationException
- 如果此内存池不支持集合使用阈值。
SecurityException
- 如果安全管理器存在,并且调用者没有ManagementPermission(“控制”)。
isCollectionUsageThresholdSupported()
,
Collection usage threshold
boolean isCollectionUsageThresholdExceeded()
UnsupportedOperationException
- 如果此内存池不支持使用阈值。
long getCollectionUsageThresholdCount()
UnsupportedOperationException
- 如果此内存池不支持集合使用阈值。
isCollectionUsageThresholdSupported()
MemoryUsage getCollectionUsage()
MBeanServer访问 :
MemoryUsage的映射类型是CompositeData ,其属性在MemoryUsage
中指定 。
MemoryUsage
表示Java虚拟机最近花费在回收未使用对象之后努力的内存池的内存使用情况;
null如果不支持此方法。
boolean isCollectionUsageThresholdSupported()