Skip to content

Commit 2f8a6cf

Browse files
author
Stefania Alborghetti
committed
DB-2993: export used direct memory
1 parent a97716c commit 2f8a6cf

File tree

5 files changed

+69
-52
lines changed

5 files changed

+69
-52
lines changed

buffer/src/main/java/io/netty/buffer/PoolArena.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -737,10 +737,10 @@ protected PoolChunk<ByteBuffer> newChunk(int pageSize, int maxOrder,
737737
int pageShifts, int chunkSize) {
738738
if (directMemoryCacheAlignment == 0) {
739739
return new PoolChunk<ByteBuffer>(this,
740-
allocateDirect(chunkSize), pageSize, maxOrder,
740+
PlatformDependent.allocateDirect(chunkSize), pageSize, maxOrder,
741741
pageShifts, chunkSize, 0);
742742
}
743-
final ByteBuffer memory = allocateDirect(chunkSize
743+
final ByteBuffer memory = PlatformDependent.allocateDirect(chunkSize
744744
+ directMemoryCacheAlignment);
745745
return new PoolChunk<ByteBuffer>(this, memory, pageSize,
746746
maxOrder, pageShifts, chunkSize,
@@ -751,26 +751,17 @@ protected PoolChunk<ByteBuffer> newChunk(int pageSize, int maxOrder,
751751
protected PoolChunk<ByteBuffer> newUnpooledChunk(int capacity) {
752752
if (directMemoryCacheAlignment == 0) {
753753
return new PoolChunk<ByteBuffer>(this,
754-
allocateDirect(capacity), capacity, 0);
754+
PlatformDependent.allocateDirect(capacity), capacity, 0);
755755
}
756-
final ByteBuffer memory = allocateDirect(capacity
756+
final ByteBuffer memory = PlatformDependent.allocateDirect(capacity
757757
+ directMemoryCacheAlignment);
758758
return new PoolChunk<ByteBuffer>(this, memory, capacity,
759759
offsetCacheLine(memory));
760760
}
761761

762-
private static ByteBuffer allocateDirect(int capacity) {
763-
return PlatformDependent.useDirectBufferNoCleaner() ?
764-
PlatformDependent.allocateDirectNoCleaner(capacity) : ByteBuffer.allocateDirect(capacity);
765-
}
766-
767762
@Override
768763
protected void destroyChunk(PoolChunk<ByteBuffer> chunk) {
769-
if (PlatformDependent.useDirectBufferNoCleaner()) {
770-
PlatformDependent.freeDirectNoCleaner(chunk.memory);
771-
} else {
772-
PlatformDependent.freeDirectBuffer(chunk.memory);
773-
}
764+
PlatformDependent.freeDirectBuffer(chunk.memory);
774765
}
775766

776767
@Override

buffer/src/main/java/io/netty/buffer/UnpooledDirectByteBuf.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public UnpooledDirectByteBuf(ByteBufAllocator alloc, int initialCapacity, int ma
6464
}
6565

6666
this.alloc = alloc;
67-
setByteBuffer(ByteBuffer.allocateDirect(initialCapacity));
67+
setByteBuffer(allocateDirect(initialCapacity));
6868
}
6969

7070
/**
@@ -103,14 +103,14 @@ protected UnpooledDirectByteBuf(ByteBufAllocator alloc, ByteBuffer initialBuffer
103103
* Allocate a new direct {@link ByteBuffer} with the given initialCapacity.
104104
*/
105105
protected ByteBuffer allocateDirect(int initialCapacity) {
106-
return ByteBuffer.allocateDirect(initialCapacity);
106+
return PlatformDependent.allocateDirectJVM(initialCapacity);
107107
}
108108

109109
/**
110110
* Free a direct {@link ByteBuffer}
111111
*/
112112
protected void freeDirect(ByteBuffer buffer) {
113-
PlatformDependent.freeDirectBuffer(buffer);
113+
PlatformDependent.freeDirectBufferJVM(buffer);
114114
}
115115

116116
private void setByteBuffer(ByteBuffer buffer) {

buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,14 @@ protected UnpooledUnsafeDirectByteBuf(ByteBufAllocator alloc, ByteBuffer initial
117117
* Allocate a new direct {@link ByteBuffer} with the given initialCapacity.
118118
*/
119119
protected ByteBuffer allocateDirect(int initialCapacity) {
120-
return ByteBuffer.allocateDirect(initialCapacity);
120+
return PlatformDependent.allocateDirectJVM(initialCapacity);
121121
}
122122

123123
/**
124124
* Free a direct {@link ByteBuffer}
125125
*/
126126
protected void freeDirect(ByteBuffer buffer) {
127-
PlatformDependent.freeDirectBuffer(buffer);
127+
PlatformDependent.freeDirectBufferJVM(buffer);
128128
}
129129

130130
final void setByteBuffer(ByteBuffer buffer, boolean tryFree) {

common/src/main/java/io/netty/util/internal/PlatformDependent.java

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -154,21 +154,16 @@ public Random current() {
154154

155155
if (maxDirectMemory == 0 || !hasUnsafe() || !PlatformDependent0.hasDirectBufferNoCleanerConstructor()) {
156156
USE_DIRECT_BUFFER_NO_CLEANER = false;
157-
DIRECT_MEMORY_COUNTER = null;
158157
} else {
159158
USE_DIRECT_BUFFER_NO_CLEANER = true;
160159
if (maxDirectMemory < 0) {
161160
maxDirectMemory = maxDirectMemory0();
162-
if (maxDirectMemory <= 0) {
163-
DIRECT_MEMORY_COUNTER = null;
164-
} else {
165-
DIRECT_MEMORY_COUNTER = new AtomicLong();
166-
}
167-
} else {
168-
DIRECT_MEMORY_COUNTER = new AtomicLong();
169161
}
170162
}
163+
164+
DIRECT_MEMORY_COUNTER = new AtomicLong();
171165
DIRECT_MEMORY_LIMIT = maxDirectMemory;
166+
172167
logger.debug("-Dio.netty.maxDirectMemory: {} bytes", maxDirectMemory);
173168

174169
int tryAllocateUninitializedArray =
@@ -380,14 +375,6 @@ public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap(Map<? extends K, ?
380375
return new ConcurrentHashMap<K, V>(map);
381376
}
382377

383-
/**
384-
* Try to deallocate the specified direct {@link ByteBuffer}. Please note this method does nothing if
385-
* the current platform does not support this operation or the specified buffer is not a direct buffer.
386-
*/
387-
public static void freeDirectBuffer(ByteBuffer buffer) {
388-
CLEANER.freeDirectBuffer(buffer);
389-
}
390-
391378
public static long directBufferAddress(ByteBuffer buffer) {
392379
return PlatformDependent0.directBufferAddress(buffer);
393380
}
@@ -584,6 +571,45 @@ public static void setMemory(long address, long bytes, byte value) {
584571
PlatformDependent0.setMemory(address, bytes, value);
585572
}
586573

574+
public static ByteBuffer allocateDirect(int capacity) {
575+
return USE_DIRECT_BUFFER_NO_CLEANER
576+
? PlatformDependent.allocateDirectNoCleaner(capacity)
577+
: allocateDirectJVM(capacity);
578+
}
579+
580+
public static void freeDirectBuffer(ByteBuffer buffer) {
581+
if (USE_DIRECT_BUFFER_NO_CLEANER) {
582+
PlatformDependent.freeDirectNoCleaner(buffer);
583+
} else {
584+
PlatformDependent.freeDirectBufferJVM(buffer);
585+
}
586+
}
587+
588+
/**
589+
* Allocate a new {@link ByteBuffer} with the given {@code capacity}. {@link ByteBuffer}s allocated with
590+
* this method <strong>MUST</strong> be deallocated via {@link #freeDirectNoCleaner(ByteBuffer)}.
591+
*/
592+
public static ByteBuffer allocateDirectJVM(int capacity) {
593+
incrementMemoryCounter(capacity);
594+
try {
595+
return ByteBuffer.allocateDirect(capacity);
596+
} catch (Throwable e) {
597+
decrementMemoryCounter(capacity);
598+
throwException(e);
599+
return null;
600+
}
601+
}
602+
603+
/**
604+
* Try to deallocate the specified direct {@link ByteBuffer}. Please note this method does nothing if
605+
* the current platform does not support this operation or the specified buffer is not a direct buffer.
606+
*/
607+
public static void freeDirectBufferJVM(ByteBuffer buffer) {
608+
int capacity = buffer.capacity();
609+
CLEANER.freeDirectBuffer(buffer);
610+
decrementMemoryCounter(capacity);
611+
}
612+
587613
/**
588614
* Allocate a new {@link ByteBuffer} with the given {@code capacity}. {@link ByteBuffer}s allocated with
589615
* this method <strong>MUST</strong> be deallocated via {@link #freeDirectNoCleaner(ByteBuffer)}.
@@ -632,32 +658,32 @@ public static void freeDirectNoCleaner(ByteBuffer buffer) {
632658
}
633659

634660
private static void incrementMemoryCounter(int capacity) {
635-
if (DIRECT_MEMORY_COUNTER != null) {
636-
for (;;) {
637-
long usedMemory = DIRECT_MEMORY_COUNTER.get();
638-
long newUsedMemory = usedMemory + capacity;
639-
if (newUsedMemory > DIRECT_MEMORY_LIMIT) {
640-
throw new OutOfDirectMemoryError("failed to allocate " + capacity
641-
+ " byte(s) of direct memory (used: " + usedMemory + ", max: " + DIRECT_MEMORY_LIMIT + ')');
642-
}
643-
if (DIRECT_MEMORY_COUNTER.compareAndSet(usedMemory, newUsedMemory)) {
644-
break;
645-
}
661+
for (;;) {
662+
long usedMemory = DIRECT_MEMORY_COUNTER.get();
663+
long newUsedMemory = usedMemory + capacity;
664+
if (DIRECT_MEMORY_LIMIT > 0 && newUsedMemory > DIRECT_MEMORY_LIMIT) {
665+
throw new OutOfDirectMemoryError("failed to allocate " + capacity
666+
+ " byte(s) of direct memory (used: " + usedMemory + ", max: " + DIRECT_MEMORY_LIMIT + ')');
667+
}
668+
if (DIRECT_MEMORY_COUNTER.compareAndSet(usedMemory, newUsedMemory)) {
669+
break;
646670
}
647671
}
648672
}
649673

650674
private static void decrementMemoryCounter(int capacity) {
651-
if (DIRECT_MEMORY_COUNTER != null) {
652-
long usedMemory = DIRECT_MEMORY_COUNTER.addAndGet(-capacity);
653-
assert usedMemory >= 0;
654-
}
675+
long usedMemory = DIRECT_MEMORY_COUNTER.addAndGet(-capacity);
676+
assert usedMemory >= 0 : "Used memory is negative: " + usedMemory;
655677
}
656678

657679
public static boolean useDirectBufferNoCleaner() {
658680
return USE_DIRECT_BUFFER_NO_CLEANER;
659681
}
660682

683+
public static long usedDirectMemory() {
684+
return DIRECT_MEMORY_COUNTER.get();
685+
}
686+
661687
/**
662688
* Compare two {@code byte} arrays for equality. For performance reasons no bounds checking on the
663689
* parameters is performed.

microbench/src/main/java/io/netty/microbench/handler/ssl/AbstractSslEngineBenchmark.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ ByteBuffer newBuffer(int size) {
109109
DIRECT {
110110
@Override
111111
ByteBuffer newBuffer(int size) {
112-
return ByteBuffer.allocateDirect(size);
112+
return PlatformDependent.allocateDirectJVM(size);
113113
}
114114

115115
@Override
116116
void freeBuffer(ByteBuffer buffer) {
117-
PlatformDependent.freeDirectBuffer(buffer);
117+
PlatformDependent.freeDirectBufferJVM(buffer);
118118
}
119119
};
120120

0 commit comments

Comments
 (0)