在 Java 中检测低内存?
Detect low memory in Java?
为了防止 OutOfMemoryError
我想创建一个代码来清除我程序中的一些缓存,当存在超出可用 RAM 的危险时。
当内存处于最大可用内存的特定百分比时,我如何从代码内部检测到内存并能够做出反应?
检测 Java 中的内存消耗以对您的代码做出反应不是一个好主意。您永远不知道垃圾收集器的行为方式、启动时间、启动频率、可以释放多少内存……
如果要防止对对象的引用阻止垃圾收集器将其删除,则可以使用弱引用 (java.lang.ref)。但是,如果您实施缓存,这可能会使缓存变得无用,因为您的缓存对象可能会被非常快速且频繁地删除。
我建议使用 LRU-Cache。这样的缓存是有一定容量的。如果超过此容量,最近最少使用的元素将被踢出缓存。这以一种简单的方式防止了缓存可以无限增长。
如果你 google 可以找到一些简单的实现:
public class LRUMap<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L;
private final int capacity;
public LRUMap(final int capacity) {
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity;
}
}
如果您需要更多,我会检查现有的缓存实现。它们可能支持额外的配置功能,例如 e. G. 缓存条目的最长期限。
事实证明(令我惊讶的是!)有一种半可靠的方法来检测超过预设阈值的内存使用情况。
MemoryPoolMXBean
class 提供了一种方法来设置内存池的使用阈值,并在池的使用超过阈值时收到通知。
您可以通过调用 ManagementFactory.getMemoryPoolMXBeans()
.
获取 JVM 的内存 MXBean 实例
有两种阈值,您需要了解它们之间的区别才能正确使用它们。比较复杂:参考javadoc。
还应该注意的是规格:
- 说不是所有的space都支持阈值检查,
表示在测试阈值交叉时没有限制:
"A Java virtual machine performs usage threshold crossing checking on a memory pool basis at its best appropriate time ..."
说明如何测试是否支持阈值检查,以及如何注册通知。
为了防止 OutOfMemoryError
我想创建一个代码来清除我程序中的一些缓存,当存在超出可用 RAM 的危险时。
当内存处于最大可用内存的特定百分比时,我如何从代码内部检测到内存并能够做出反应?
检测 Java 中的内存消耗以对您的代码做出反应不是一个好主意。您永远不知道垃圾收集器的行为方式、启动时间、启动频率、可以释放多少内存……
如果要防止对对象的引用阻止垃圾收集器将其删除,则可以使用弱引用 (java.lang.ref)。但是,如果您实施缓存,这可能会使缓存变得无用,因为您的缓存对象可能会被非常快速且频繁地删除。
我建议使用 LRU-Cache。这样的缓存是有一定容量的。如果超过此容量,最近最少使用的元素将被踢出缓存。这以一种简单的方式防止了缓存可以无限增长。
如果你 google 可以找到一些简单的实现:
public class LRUMap<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L;
private final int capacity;
public LRUMap(final int capacity) {
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity;
}
}
如果您需要更多,我会检查现有的缓存实现。它们可能支持额外的配置功能,例如 e. G. 缓存条目的最长期限。
事实证明(令我惊讶的是!)有一种半可靠的方法来检测超过预设阈值的内存使用情况。
MemoryPoolMXBean
class 提供了一种方法来设置内存池的使用阈值,并在池的使用超过阈值时收到通知。
您可以通过调用 ManagementFactory.getMemoryPoolMXBeans()
.
有两种阈值,您需要了解它们之间的区别才能正确使用它们。比较复杂:参考javadoc。
还应该注意的是规格:
- 说不是所有的space都支持阈值检查,
表示在测试阈值交叉时没有限制:
"A Java virtual machine performs usage threshold crossing checking on a memory pool basis at its best appropriate time ..."
说明如何测试是否支持阈值检查,以及如何注册通知。