// -- Direct memory management --
// A user-settable upper limit on the maximum amount of allocatable
// direct buffer memory. This value may be changed during VM
// initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
private static volatile long maxMemory = VM.maxDirectMemory();
private static volatile long reservedMemory;
private static volatile long totalCapacity;
private static volatile long count;
private static boolean memoryLimitSet = false;
// These methods should be called whenever direct memory is allocated or
// freed. They allow the user to control the amount of direct memory
// which a process may access. All sizes are specified in bytes.
static void reserveMemory(long size, int cap) {
synchronized (Bits.class) {
if (!memoryLimitSet && VM.isBooted()) {
maxMemory = VM.maxDirectMemory();
memoryLimitSet = true;
}
// -XX:MaxDirectMemorySize limits the total capacity rather than the
// actual memory usage, which will differ when buffers are page
// aligned.
if (cap <= maxMemory - totalCapacity) {
reservedMemory += size;
totalCapacity += cap;
count++;
return;
}
}
System.gc();
try {
Thread.sleep(100);
} catch (InterruptedException x) {
// Restore interrupt status
Thread.currentThread().interrupt();
}
synchronized (Bits.class) {
if (totalCapacity + cap > maxMemory)
throw new OutOfMemoryError("Direct buffer memory");
reservedMemory += size;
totalCapacity += cap;
count++;
}
}
System.gc()不一定都会立刻去做GC,也不一定会去做GC。
/**
* -XX:MaxDirectMemorySize=256m -XX:+PrintGCDetails -XX:+DisableExplicitGC
* 如果不设置此参数,默认是Xmx-Survivor大小
* @author xixicat
* @created 2014-10-03
*/
public class ByteBufferOOM {
//-XX:MaxDirectMemorySize=256m
public static void main(String []args) {
//直接OOM
// ByteBuffer.allocateDirect(257 * 1024 * 1024);
//先申请256M,再申请1M,是不会OOM的,如果加上-XX:+DisableExplicitGC则OOM
ByteBuffer.allocateDirect(256 * 1024 * 1024);
//这里直接GC
ByteBuffer.allocateDirect(1024 * 1024);
}
}
禁用显示GC后,发现DirectBuffer满后不会触发FullGC,直接发生OOM
如果增加一个引用,第一次分配256M,则直接OOM
import sun.nio.ch.DirectBuffer;
import java.nio.ByteBuffer;
/**
* -XX:MaxDirectMemorySize=256m -XX:+PrintGCDetails
* -XX:+DisableExplicitGC
* 如果不设置此参数,默认是Xmx-Survivor大小
* @author xixicat
* @created 2014-10-03
*/
public class ByteBufferOOM {
public static void directOOM(){
//直接OOM
ByteBuffer.allocateDirect(257 * 1024 * 1024);
}
public static void fullGC(){
//先申请256M,再申请1M,是不会OOM的
ByteBuffer.allocateDirect(256 * 1024 * 1024);
//这里直接GC
ByteBuffer.allocateDirect(1024 * 1024);
}
public static void disableGCOOM(){
//加上-XX:+DisableExplicitGC则OOM
ByteBuffer.allocateDirect(256 * 1024 * 1024);
ByteBuffer.allocateDirect(1024 * 1024);
}
public static void gcReference(){
//增加引用,则直接OOM
//Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
//DirectBuffer的GC规则与堆对象的回收规则一样,只有垃圾对象才被回收,而判定是否为垃圾对象
//依据引用树中的存活节点来判定
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(256 * 1024 * 1024);
ByteBuffer.allocateDirect(1024 * 1024);
}
public static void manualClear(){
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(256 * 1024 * 1024);
//手工释放,无需等到GC才释放,这个时候可以直接禁用显示GC
((DirectBuffer)byteBuffer).cleaner().clean();
ByteBuffer.allocateDirect(1024 * 1024);
}
public static void main(String []args) {
// directOOM();
// fullGC();
// disableGCOOM();
// gcReference();
manualClear();
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。