Skip to content

Commit

Permalink
* Add PointerBufferPoolMXBean to track allocations and deallocatio…
Browse files Browse the repository at this point in the history
…ns of `Pointer` (pull #413)
  • Loading branch information
digiovinazzo authored Aug 6, 2020
1 parent 52951ca commit 341f65c
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/main/java/org/bytedeco/javacpp/Pointer.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicInteger;
import org.bytedeco.javacpp.annotation.Name;
import org.bytedeco.javacpp.annotation.Platform;
import org.bytedeco.javacpp.tools.Generator;
import org.bytedeco.javacpp.tools.PointerBufferPoolMXBean;
import org.bytedeco.javacpp.tools.Logger;

/**
Expand Down Expand Up @@ -285,6 +285,7 @@ static class DeallocatorReference extends PhantomReference<Pointer> implements D
Deallocator deallocator;

static volatile long totalBytes = 0;
static volatile long totalCount = 0;
long bytes;

AtomicInteger count;
Expand All @@ -298,6 +299,7 @@ final void add() {
next.prev = head = this;
}
totalBytes += bytes;
totalCount++;
}
}

Expand All @@ -316,6 +318,7 @@ final void remove() {
}
prev = next = this;
totalBytes -= bytes;
totalCount--;
}
}

Expand Down Expand Up @@ -506,6 +509,11 @@ public static long parseBytes(String string, long relativeMultiple) throws Numbe
} catch (Throwable t) {
logger.warn("Could not load Pointer: " + t);
}

String mx = System.getProperty("org.bytedeco.javacpp.mxbean", "false").toLowerCase();
if (mx.equals("true") || mx.equals("t") || mx.equals("")) {
PointerBufferPoolMXBean.register();
}
}

/** Clears, deallocates, and removes all garbage collected objects from the {@link #referenceQueue}. */
Expand All @@ -527,6 +535,11 @@ public static long totalBytes() {
return DeallocatorReference.totalBytes;
}

/** Returns {@link DeallocatorReference#totalCount}, current number of pointers tracked by deallocators. */
public static long totalCount() {
return DeallocatorReference.totalCount;
}

/** Returns {@link #maxPhysicalBytes}, the maximum amount of physical memory that should be used. */
public static long maxPhysicalBytes() {
return maxPhysicalBytes;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.bytedeco.javacpp.tools;

import org.bytedeco.javacpp.Pointer;

import javax.management.*;
import java.lang.management.BufferPoolMXBean;
import java.lang.management.ManagementFactory;

public class PointerBufferPoolMXBean implements BufferPoolMXBean {

private static final Logger LOGGER = Logger.create(PointerBufferPoolMXBean.class);
private static final String JAVACPP_MXBEAN_NAME = "javacpp";
private static final ObjectName OBJECT_NAME;

static {
ObjectName objectName = null;
try {
objectName = new ObjectName("java.nio:type=BufferPool,name=" + JAVACPP_MXBEAN_NAME);
} catch (MalformedObjectNameException e) {
LOGGER.warn("Could not create OBJECT_NAME for " + JAVACPP_MXBEAN_NAME);
}
OBJECT_NAME = objectName;
}

@Override
public String getName() {
return JAVACPP_MXBEAN_NAME;
}

@Override
public ObjectName getObjectName() {
return OBJECT_NAME;
}

@Override
public long getCount() {
return Pointer.totalCount();
}

@Override
public long getTotalCapacity() {
return Pointer.maxPhysicalBytes();
}

@Override
public long getMemoryUsed() {
return Pointer.totalBytes();
}

public static void register() {
if (OBJECT_NAME != null) {
try {
ManagementFactory.getPlatformMBeanServer().registerMBean(new PointerBufferPoolMXBean(), OBJECT_NAME);
} catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
LOGGER.warn("Could not register " + JAVACPP_MXBEAN_NAME + " BufferPoolMXBean");
}
}
}
}

0 comments on commit 341f65c

Please sign in to comment.