Class NativeMemoryCleaner
java.lang.Object
express.mvp.myra.transport.memory.NativeMemoryCleaner
Provides automatic native memory cleanup using the Cleaner API.
This class ensures that native resources are released even if explicit close() is not
called. It uses phantom references to trigger cleanup when the owning object becomes unreachable.
Design Rationale
While explicit resource management via AutoCloseable is preferred, this cleaner
provides a safety net for:
- Exception paths that bypass normal cleanup
- Complex object graphs where ownership is unclear
- Third-party code that may not properly close resources
Usage Example
class NativeBuffer implements AutoCloseable {
private final Arena arena;
private final MemorySegment segment;
private final Cleaner.Cleanable cleanable;
public NativeBuffer(long size) {
this.arena = Arena.ofConfined();
this.segment = arena.allocate(size);
// Register cleanup action - must not capture 'this'
Arena arenaRef = this.arena;
this.cleanable = NativeMemoryCleaner.register(this, () -> {
arenaRef.close();
});
}
@Override
public void close() {
cleanable.clean(); // Explicit cleanup, prevents GC-triggered clean
}
}
Important Constraints
- Cleanup actions must not reference the registered object (prevents GC)
- Cleanup actions should be idempotent (may be called multiple times)
- Cleanup runs on the cleaner thread, not the allocating thread
Statistics
This class tracks registration and cleanup statistics for monitoring and debugging.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classCleanable wrapper that properly tracks explicit cleanup. -
Method Summary
Modifier and TypeMethodDescriptionstatic longReturns the number of active registrations (registered - cleaned).static longReturns the number of explicit cleanups (via clean()).static longReturns the number of GC-triggered cleanups.static longReturns the total number of registrations.static Cleaner.CleanableRegisters an object for cleanup when it becomes phantom reachable.registerTracked(Object object, Runnable cleanupAction) Creates a tracked cleanable that properly distinguishes explicit vs GC cleanup.static voidResets all statistics (for testing).
-
Method Details
-
register
Registers an object for cleanup when it becomes phantom reachable.The cleanup action is called either:
- Explicitly via
Cleaner.Cleanable.clean(), or - Automatically when the object is garbage collected
Critical: The cleanup action must not reference the registered object, as this would prevent garbage collection.
- Parameters:
object- the object to monitor for cleanupcleanupAction- the action to run on cleanup (must not reference object)- Returns:
- a Cleanable that can be used for explicit cleanup
- Explicitly via
-
getRegistrationCount
public static long getRegistrationCount()Returns the total number of registrations.- Returns:
- registration count
-
getExplicitCleanupCount
public static long getExplicitCleanupCount()Returns the number of explicit cleanups (via clean()).- Returns:
- explicit cleanup count
-
getGcCleanupCount
public static long getGcCleanupCount()Returns the number of GC-triggered cleanups.- Returns:
- GC cleanup count
-
getActiveCount
public static long getActiveCount()Returns the number of active registrations (registered - cleaned).- Returns:
- active registration count
-
resetStatistics
public static void resetStatistics()Resets all statistics (for testing). -
registerTracked
public static NativeMemoryCleaner.TrackedCleanable registerTracked(Object object, Runnable cleanupAction) Creates a tracked cleanable that properly distinguishes explicit vs GC cleanup.- Parameters:
object- the object to monitorcleanupAction- the cleanup action- Returns:
- a cleanable that tracks cleanup type
-