DirectByteBuffer(intcap){// package-privatesuper(-1,0,cap,cap);booleanpa=VM.isDirectMemoryPageAligned();intps=Bits.pageSize();longsize=Math.max(1L,(long)cap+(pa?ps:0));Bits.reserveMemory(size,cap);longbase=0;try{base=unsafe.allocateMemory(size);}catch(OutOfMemoryErrorx){Bits.unreserveMemory(size,cap);throwx;}unsafe.setMemory(base,size,(byte)0);if(pa&&(base%ps!=0)){// Round up to page boundaryaddress=base+ps-(base&(ps-1));}else{address=base;}cleaner=Cleaner.create(this,newDeallocator(base,size,cap));att=null;}
staticvoidreserveMemory(longsize,intcap){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(InterruptedExceptionx){// Restore interrupt statusThread.currentThread().interrupt();}synchronized(Bits.class){if(totalCapacity+cap>maxMemory)thrownewOutOfMemoryError("Direct buffer memory");reservedMemory+=size;totalCapacity+=cap;count++;}}
extern"C"jobjectJNICALLjni_NewDirectByteBuffer(JNIEnv*env,void*address,jlongcapacity){// thread_from_jni_environment() will block if VM is gone.JavaThread*thread=JavaThread::thread_from_jni_environment(env);JNIWrapper("jni_NewDirectByteBuffer");#ifndefUSDT2DTRACE_PROBE3(hotspot_jni,NewDirectByteBuffer__entry,env,address,capacity);#else/* USDT2 */HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY(env,address,capacity);#endif/* USDT2 */if(!directBufferSupportInitializeEnded){if(!initializeDirectBufferSupport(env,thread)){#ifndefUSDT2DTRACE_PROBE1(hotspot_jni,NewDirectByteBuffer__return,NULL);#else/* USDT2 */HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(NULL);#endif/* USDT2 */returnNULL;}}// Being paranoid about accidental sign extension on addressjlongaddr=(jlong)((uintptr_t)address);// NOTE that package-private DirectByteBuffer constructor currently// takes int capacityjintcap=(jint)capacity;jobjectret=env->NewObject(directByteBufferClass,directByteBufferConstructor,addr,cap);#ifndefUSDT2DTRACE_PROBE1(hotspot_jni,NewDirectByteBuffer__return,ret);#else/* USDT2 */HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(ret);#endif/* USDT2 */returnret;}