我希望能够检测空闲内存是否不足(比如只剩15%的空闲内存),并且采取一些措施。
我曾尝试使用
我曾尝试使用
Runtime
内存指标,但好像表现不一致。
这是我的测试应用:
import java.util.*;
public class Memory
{
static final int BYTES_PER_MB = 1024*1024;
public static void main(String[] args) {
Queue<byte[]> q = new LinkedList<>();
int allocated = 0;
while (true) {
q.add(new byte[BYTES_PER_MB * 100]);
allocated += 100;
System.out.printf("Allocated 100m (total allocated=%d)%n", allocated);
printMem();
}
}
public static void printMem() {
long max = Runtime.getRuntime().maxMemory() / BYTES_PER_MB;
long total = Runtime.getRuntime().totalMemory() / BYTES_PER_MB;
long free = Runtime.getRuntime().freeMemory() / BYTES_PER_MB;
long totalFree = free+(max-total); // allocated free + memory that can be allocated
System.out.printf("MEM: max=%dm, total=%dm, free=%d, (total free=%d)%n", max, total, free, totalFree);
}
}
这是我所得到的结果:
JVM | Command | Total free before OOM
--------------------------------------------------------------------------------------------------
Oracle Java 1.8.0_191-b12 64-Bit Server | java -Xmx1024m -Xms10m Memory | 309
Oracle Java 1.8.0_191-b12 64-Bit Server | java -Xmx1024m Memory | 205
Oracle Java 11.0.2+9-LTS 64-Bit Server | java -Xmx1024m -Xms10m Memory | 12
Oracle Java 11.0.2+9-LTS 64-Bit Server | java -Xmx1024m Memory" | 12
针对Java 11的结果是有意义的,但我不理解Java 8的结果。
- 为什么尽管我有足够的内存,我仍然无法分配空间?(我认为这不是碎片化问题,因为堆主要由100m的块组成,并且如果我按10m的块进行分配也会失败)
- 如果我指定一个较低的
-Xmx
,为什么我可以分配更少的内存?难道这只影响初始堆大小吗?