Here is the code for the java.nio.DirectByteBuffer(int) constructor, which is contained in the Direct-X-Buffer.java.template file, starting at line 117: Direct$Type$Buffer$RW$(int cap) { // package-private #if[rw] super(-1, 0, cap, cap); boolean pa = VM.isDirectMemoryPageAligned(); int ps = Bits.pageSize(); long size = Math.max(1L, (long)cap + (pa ? ps : 0)); Bits.reserveMemory(size, cap);
long base = 0; try { base = unsafe.allocateMemory(size); } catch (OutOfMemoryError x) { Bits.unreserveMemory(size, cap); throw x; } unsafe.setMemory(base, size, (byte) 0); if (pa && (base % ps != 0)) { // Round up to page boundary address = base + ps - (base & (ps - 1)); } else { address = base; } cleaner = Cleaner.create(this, new Deallocator(base, size, cap)); att = null; #else[rw] super(cap); this.isReadOnly = true; #end[rw] } A memory leak of the memory allocated by the base = unsafe.allocateMemory(size) statement in line 127 of the Direct-X-Buffer.java.template file can occur if an OutOfMemoryError is thrown by the cleaner = Cleaner.create(this, new Deallocator(base, size, cap)) statement in line 139 of the Direct-X-Buffer.java.template file. Here is one way to fix the issue: Bits.reserveMemory(size, cap); long base = 0; try { base = unsafe.allocateMemory(size); unsafe.setMemory(base, size, (byte)0); if (pa && (base % ps != 0)) { // Round up to page boundary address = base + ps - (base & (ps - 1)); } else { address = base; } cleaner = Cleaner.create(this, new Deallocator(base, size, cap)); } catch(OutOfMemoryError x) { Bits.unreserveMemory(size, cap); if(base != 0 && cleaner == null) { // If the memory block has been allocated, but cleaner has not yet been allocated, free the allocated // memory block before rethrowing the OutOfMemoryError. address = 0; unsafe.freeMemory(base); } throw x; } att = null;