> Adding in core-libs-dev as there's nothing related to hotspot directly here. > > David
Thought it was best to pass this through hotspot lists first, as full completion of the native side of things will probably require hotspot changes. You're quite right though, I should have cc'd hotspot *and* core libs. - Adam > > On 14/02/2018 9:32 PM, Adam Farley8 wrote: >> Hi All, >> >> Currently, diagnostic core files generated from OpenJDK seem to lump all >> of the >> native memory usages together, making it near-impossible for someone to >> figure >> out *what* is using all that memory in the event of a memory leak. >> >> The OpenJ9 VM has a feature which allows it to track the allocation of >> native >> memory for Direct Byte Buffers (DBBs), and to supply that information into >> the >> cores when they are generated. This makes it a *lot* easier to find out >> what is using >> all that native memory, making memory leak resolution less like some dark >> art, and >> more like logical debugging. >> >> To use this feature, there is a native method referenced in Unsafe.java. >> To open >> up this feature so that any VM can make use of it, the java code below >> sets the >> stage for it. This change starts letting people call DBB-specific methods >> when >> allocating native memory, and getting into the habit of using it. >> >> Thoughts? >> >> Best Regards >> >> Adam Farley >> >> P.S. Code: >> >> diff --git >> a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template >> b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template >> --- a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template >> +++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template >> @@ -85,7 +85,7 @@ >> // Paranoia >> return; >> } >> - UNSAFE.freeMemory(address); >> + UNSAFE.freeDBBMemory(address); >> address = 0; >> Bits.unreserveMemory(size, capacity); >> } >> @@ -118,7 +118,7 @@ >> >> long base = 0; >> try { >> - base = UNSAFE.allocateMemory(size); >> + base = UNSAFE.allocateDBBMemory(size); >> } catch (OutOfMemoryError x) { >> Bits.unreserveMemory(size, cap); >> throw x; >> diff --git a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java >> b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java >> --- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java >> +++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java >> @@ -632,6 +632,26 @@ >> } >> >> /** >> + * Allocates a new block of native memory for DirectByteBuffers, of >> the >> + * given size in bytes. The contents of the memory are >> uninitialized; >> + * they will generally be garbage. The resulting native pointer will >> + * never be zero, and will be aligned for all value types. Dispose >> of >> + * this memory by calling {@link #freeDBBMemory} or resize it with >> + * {@link #reallocateDBBMemory}. >> + * >> + * @throws RuntimeException if the size is negative or too large >> + * for the native size_t type >> + * >> + * @throws OutOfMemoryError if the allocation is refused by the >> system >> + * >> + * @see #getByte(long) >> + * @see #putByte(long, byte) >> + */ >> + public long allocateDBBMemory(long bytes) { >> + return allocateMemory(bytes); >> + } >> + >> + /** >> * Resizes a new block of native memory, to the given size in bytes. >> The >> * contents of the new block past the size of the old block are >> * uninitialized; they will generally be garbage. The resulting >> native >> @@ -687,6 +707,27 @@ >> } >> >> /** >> + * Resizes a new block of native memory for DirectByteBuffers, to the >> + * given size in bytes. The contents of the new block past the size >> of >> + * the old block are uninitialized; they will generally be garbage. >> The >> + * resulting native pointer will be zero if and only if the requested >> size >> + * is zero. The resulting native pointer will be aligned for all >> value >> + * types. Dispose of this memory by calling {@link #freeDBBMemory}, >> or >> + * resize it with {@link #reallocateDBBMemory}. The address passed >> to >> + * this method may be null, in which case an allocation will be >> performed. >> + * >> + * @throws RuntimeException if the size is negative or too large >> + * for the native size_t type >> + * >> + * @throws OutOfMemoryError if the allocation is refused by the >> system >> + * >> + * @see #allocateDBBMemory >> + */ >> + public long reallocateDBBMemory(long address, long bytes) { >> + return reallocateMemory(address, bytes); >> + } >> + >> + /** >> * Sets all bytes in a given block of memory to a fixed value >> * (usually zero). >> * >> @@ -918,6 +959,17 @@ >> checkPointer(null, address); >> } >> >> + /** >> + * Disposes of a block of native memory, as obtained from {@link >> + * #allocateDBBMemory} or {@link #reallocateDBBMemory}. The address >> passed >> + * to this method may be null, in which case no action is taken. >> + * >> + * @see #allocateDBBMemory >> + */ >> + public void freeDBBMemory(long address) { >> + freeMemory(address); >> + } >> + >> /// random queries >> >> /** >> >> Unless stated otherwise above: >> IBM United Kingdom Limited - Registered in England and Wales with number >> 741598. >> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU >> > Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU