JVM直接内存测试
测试代码如下:
导入这两个包
import com.sun.management.OperatingSystemMXBean;
import sun.nio.ch.DirectBuffer;
有可能引起IDE报错
Eclipse 默认把这些受访问限制的API设成了ERROR。
Windows -> Preferences -> Java -> Compiler -> Errors/Warnings ->
Deprecated and trstricted API -> Forbidden reference (access rules): -> change to warning
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.lang.management.RuntimeMXBean;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import com.sun.management.OperatingSystemMXBean;
import sun.nio.ch.DirectBuffer;
public class TestDirectMemory {
public static void main(String[] args) throws InterruptedException {
System.out.println("之前的内存占用:" + getMemoryLog());
//分配1G直接内存
ByteBuffer bb = ByteBuffer.allocateDirect(1024 * 1024 * 1024);
System.out.println("之后的内存占用:" + getMemoryLog());
}
public static String getMemoryLog() {
OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
// 当前使用的内存(堆内存和非堆内存)
long totalMemory = Runtime.getRuntime().totalMemory();
// 剩余内存
long freeMemory = Runtime.getRuntime().freeMemory();
// JVM最大可使用内存
long maxMemory = Runtime.getRuntime().maxMemory();
// 总的物理内存
long totalMemorySize = osmxb.getTotalPhysicalMemorySize();
// 剩余的物理内存
long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize();
// 已使用的物理内存
long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb.getFreePhysicalMemorySize());
RuntimeMXBean runtimeMBean = (RuntimeMXBean) ManagementFactory.getRuntimeMXBean();
long prevUpTime = runtimeMBean.getUptime();
long prevProcessCpuTime = osmxb.getProcessCpuTime();
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
StringBuffer sb = new StringBuffer();
sb.append("|内存|当前使用的内存:" + size2str(totalMemory));
sb.append("|剩余内存:" + size2str(freeMemory));
sb.append("|最大可使用内存:" + size2str(maxMemory));
sb.append("|总的物理内存:" + size2str(totalMemorySize));
sb.append("|剩余的物理内存:" + size2str(freePhysicalMemorySize));
sb.append("|已使用的物理内存:" + size2str(usedMemory));
MemoryUsage heap = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
MemoryUsage none = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
sb.append("|堆:" + size2str(heap.getUsed()) + "/" + size2str(heap.getMax()));
sb.append("|非堆:" + size2str(none.getUsed()) + "/" + size2str(none.getMax()));
int nCPUs = osmxb.getAvailableProcessors();
long uptime = runtimeMBean.getUptime();
long processCpuTime = osmxb.getProcessCpuTime();
long elapsedCpu = processCpuTime - prevProcessCpuTime;
long elaspedTime = uptime - prevUpTime;
float cpuUsage = elapsedCpu / (elaspedTime * 10000F * nCPUs);
sb.append("|Cpu使用率:" + cpuUsage);
if (freeMemory < (totalMemory / 20)) {
sb.append(",警告,内存空间小于:" + freeMemory + "MB");
}
return sb.toString();
}
public static final long ONE_KB = 1024;
public static final long ONE_MB = ONE_KB * ONE_KB;
public static final long ONE_GB = ONE_KB * ONE_MB;
public static String size2str(long size) {
StringBuilder builder = new StringBuilder();
if (size / ONE_GB > 0) {
builder.append(size / ONE_GB).append("G ");
builder.append(size2str(size % ONE_GB));
} else if (size / ONE_MB > 0) {
builder.append(size / ONE_MB).append("M ");
builder.append(size2str(size % ONE_MB));
} else if (size / ONE_KB > 0) {
builder.append(size / ONE_KB).append("K ");
builder.append(size2str(size % ONE_KB));
} else {
builder.append(size).append("bytes");
}
return builder.toString();
}
}
测试1:
JVM参数:
-Xmx100m
输出:
之前的内存占用:|内存|当前使用的内存:96M 0bytes|剩余内存:93M 966K 400bytes|最大可使用内存:96M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:3G 335M 432K 0bytes|已使用的物理内存:4G 588M 672K 0bytes|堆:2M 57K 624bytes/96M 0bytes|非堆:3M 42K 760bytes/130M 0bytes|Cpu使用率:0.0
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:658)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:306)
at TestDirectMemory.main(TestDirectMemory.java:21)
结果:
运行异常,因为如果没设置-XX:MaxDirectMemorySize,则默认与-Xmx参数值相同,分配1G直接内存超出限制范围。
测试2:
JVM参数:
-Xmx2G
输出:
之前的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:118M 921K 184bytes|最大可使用内存:1G 796M 512K 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:3G 264M 880K 0bytes|已使用的物理内存:4G 659M 224K 0bytes|堆:2M 614K 840bytes/1G 796M 512K 0bytes|非堆:3M 42K 952bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:118M 921K 184bytes|最大可使用内存:1G 796M 512K 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 272M 400K 0bytes|已使用的物理内存:5G 651M 704K 0bytes|堆:2M 614K 840bytes/1G 796M 512K 0bytes|非堆:3M 73K 520bytes/130M 0bytes|Cpu使用率:0.0
结果:
运行正常,因为1G小于2G,属于范围内分配。很明显可以看出来,物理内存少了1G
测试3:
JVM参数:
-Xmx1G -XX:MaxDirectMemorySize=512M
输出:
之前的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:118M 921K 104bytes|最大可使用内存:910M 512K 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:3G 274M 428K 0bytes|已使用的物理内存:4G 649M 676K 0bytes|堆:2M 614K 920bytes/910M 512K 0bytes|非堆:3M 42K 696bytes/130M 0bytes|Cpu使用率:0.0
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:658)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:306)
at TestDirectMemory.main(TestDirectMemory.java:21)
结果:
运行异常,分配的直接内存1G超过限定的521M
测试4:
代码修改如下:
System.out.println("之前的内存占用:" + getMemoryLog());
//分配1G直接内存
ByteBuffer bb = ByteBuffer.allocateDirect(1024 * 1024 * 1024);
System.out.println("之后的内存占用1:" + getMemoryLog());
//清除直接缓存
((DirectBuffer)bb).cleaner().clean();
System.out.println("之后的内存占用2:" + getMemoryLog());
JVM参数:
无
输出:
之前的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:3G 264M 356K 0bytes|已使用的物理内存:4G 659M 748K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 9K 632bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用1:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 270M 904K 0bytes|已使用的物理内存:5G 653M 200K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 24bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用2:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:3G 258M 148K 0bytes|已使用的物理内存:4G 665M 976K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 24bytes/130M 0bytes|Cpu使用率:0.0
结果:
很明显,内存得到了释放
测试5:
测试一下会不会被system.gc()
代码修改如下:
System.out.println("之前的内存占用:" + getMemoryLog());
//分配1G直接内存
ByteBuffer bb = ByteBuffer.allocateDirect(1024 * 1024 * 1024);
System.out.println("之后的内存占用1:" + getMemoryLog());
System.gc();
System.out.println("之后的内存占用2:" + getMemoryLog());
JVM参数:
无
输出:
之前的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:3G 262M 1008K 0bytes|已使用的物理内存:4G 661M 96K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 9K 520bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用1:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 269M 896K 0bytes|已使用的物理内存:5G 654M 208K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 39K 936bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用2:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:120M 318K 1000bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 268M 648K 0bytes|已使用的物理内存:5G 655M 456K 0bytes|堆:1M 858K 736bytes/1G 775M 0bytes|非堆:3M 38K 1016bytes/130M 0bytes|Cpu使用率:0.0
结果:
虽然强制调用了sytem.gc() 但是因为堆状况良好,所以没有被回收
测试6
测试一下会不会被JVM自动回收掉
代码修改如下:
System.out.println("之前的内存占用:" + getMemoryLog());
//分配1G直接内存
ByteBuffer bb = ByteBuffer.allocateDirect(1024 * 1024 * 1024);
for(;;){
System.out.println("之后的内存占用:" + getMemoryLog());
TimeUnit.SECONDS.sleep(1);
}
JVM参数:
无
输出:
之前的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:3G 272M 404K 0bytes|已使用的物理内存:4G 651M 700K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 9K 496bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 280M 12K 0bytes|已使用的物理内存:5G 644M 68K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 16bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 280M 0bytes|已使用的物理内存:5G 644M 80K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 16bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 283M 804K 0bytes|已使用的物理内存:5G 640M 300K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 16bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 282M 184K 0bytes|已使用的物理内存:5G 641M 920K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 16bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 285M 0bytes|已使用的物理内存:5G 639M 80K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 16bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 289M 244K 0bytes|已使用的物理内存:5G 634M 860K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 16bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 290M 100K 0bytes|已使用的物理内存:5G 633M 1004K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 16bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 290M 268K 0bytes|已使用的物理内存:5G 633M 836K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 16bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 292M 188K 0bytes|已使用的物理内存:5G 631M 916K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 16bytes/130M 0bytes|Cpu使用率:0.0
之后的内存占用:|内存|当前使用的内存:121M 512K 0bytes|剩余内存:119M 562K 736bytes|最大可使用内存:1G 775M 0bytes|总的物理内存:7G 924M 80K 0bytes|剩余的物理内存:2G 291M 536K 0bytes|已使用的物理内存:5G 632M 568K 0bytes|堆:1M 973K 288bytes/1G 775M 0bytes|非堆:3M 40K 16bytes/130M 0bytes|Cpu使用率:0.0
结果:
我们看到很长的一段时间内,内存一直没有得到释放
JVM直接内存
猜你喜欢
转载自watersrc.iteye.com/blog/2345036
今日推荐
周排行