Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Derive direct memory used count from netty counter #223

Merged
merged 2 commits into from
Feb 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.yahoo.pulsar.broker.stats.metrics;

import java.lang.management.ManagementFactory;
import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.TimeUnit;

Expand All @@ -34,6 +35,8 @@
import io.netty.buffer.PoolChunkListMetric;
import io.netty.buffer.PoolChunkMetric;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.util.internal.PlatformDependent;
import java.util.concurrent.atomic.AtomicLong;

public class JvmMetrics extends AbstractMetrics {

Expand All @@ -46,6 +49,17 @@ public class JvmMetrics extends AbstractMetrics {
private volatile long currentOldGcCount = 0;
private volatile long accumulatedOldGcTime = 0;
private volatile long currentOldGcTime = 0;

private static final Logger log = LoggerFactory.getLogger(JvmMetrics.class);
private static Field directMemoryUsage = null;
static {
try {
directMemoryUsage = PlatformDependent.class.getDeclaredField("DIRECT_MEMORY_COUNTER");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's called a counter.. does it go down when the memory is released? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, updated test-case with the release call.

directMemoryUsage.setAccessible(true);
} catch (Exception e) {
log.warn("Failed to access netty DIRECT_MEMORY_COUNTER field {}", e.getMessage());
}
}

public JvmMetrics(PulsarService pulsar) {
super(pulsar);
Expand All @@ -64,8 +78,7 @@ public List<Metrics> generate() {
m.put("jvm_max_memory", r.maxMemory());
m.put("jvm_total_memory", r.totalMemory());

m.put("jvm_direct_memory_used",
sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPool().getMemoryUsed());
m.put("jvm_direct_memory_used", getJvmDirectMemoryUsed());
m.put("jvm_max_direct_memory", sun.misc.VM.maxDirectMemory());
m.put("jvm_thread_cnt", getThreadCount());

Expand Down Expand Up @@ -95,6 +108,20 @@ public List<Metrics> generate() {
return Lists.newArrayList(m);
}

@SuppressWarnings("restriction")
public static long getJvmDirectMemoryUsed() {
if (directMemoryUsage != null) {
try {
return ((AtomicLong) directMemoryUsage.get(null)).get();
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug("Failed to get netty-direct-memory used count {}", e.getMessage());
}
}
}
return sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPool().getMemoryUsed();
}

private static ObjectName youngGenName = null;
private static ObjectName oldGenName = null;

Expand Down Expand Up @@ -144,5 +171,4 @@ private long getThreadCount() {
return parentThreadGroup.activeCount();
}

private static final Logger log = LoggerFactory.getLogger(JvmMetrics.class);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@

import com.yahoo.pulsar.broker.service.BrokerTestBase;
import com.yahoo.pulsar.broker.stats.BookieClientStatsGenerator;
import com.yahoo.pulsar.broker.stats.metrics.JvmMetrics;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;

/**
*/
Expand All @@ -49,4 +53,33 @@ public void testBookieClientStatsGenerator() throws Exception {
Map<String, Map<String, PendingBookieOpsStats>> stats = BookieClientStatsGenerator.generate(super.getPulsar());
assertEquals((boolean) stats.isEmpty(), true);
}

@Test
public void testJvmDirectMemoryUsedMetric() throws Exception {
PooledByteBufAllocator allocator = new PooledByteBufAllocator( //
true, // preferDirect
0, // nHeapArenas,
1, // nDirectArena
8192, // pageSize
11, // maxOrder
64, // tinyCacheSize
32, // smallCacheSize
8 // normalCacheSize
);
int allocateMemory = 17777216;
long directMemory1 = JvmMetrics.getJvmDirectMemoryUsed();
ByteBuf buf2 = allocator.directBuffer(allocateMemory, allocateMemory);
long directMemory2 = JvmMetrics.getJvmDirectMemoryUsed();
assertEquals(directMemory2, directMemory1 + allocateMemory);
ByteBuf buf3 = allocator.directBuffer(allocateMemory, allocateMemory);
long directMemory3 = JvmMetrics.getJvmDirectMemoryUsed();
assertEquals(directMemory3, directMemory2 + allocateMemory);
buf3.release();
directMemory3 = JvmMetrics.getJvmDirectMemoryUsed();
assertEquals(directMemory3, directMemory2);
buf2.release();
directMemory2 = JvmMetrics.getJvmDirectMemoryUsed();
assertEquals(directMemory2, directMemory1);

}
}