8147443: Use the Common Cleaner in Marlin OffHeapArray
Summary: OffHeapArray clean-up to use the jdk.internal.ref.Cleaner to free unsafe arrays (PhantomReference)
Reviewed-by: prr, rriggs, mchung
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java Thu Jan 14 23:14:01 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java Wed Jan 20 22:53:26 2016 +0100
@@ -110,7 +110,7 @@
MarlinCache(final RendererContext rdrCtx) {
this.rdrCtx = rdrCtx;
- rowAAChunk = new OffHeapArray(rdrCtx, INITIAL_CHUNK_ARRAY);
+ rowAAChunk = new OffHeapArray(rdrCtx.cleanerObj, INITIAL_CHUNK_ARRAY); // 64K
touchedTile = touchedTile_initial;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/OffHeapArray.java Thu Jan 14 23:14:01 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/OffHeapArray.java Wed Jan 20 22:53:26 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,9 @@
package sun.java2d.marlin;
-import java.lang.ref.PhantomReference;
-import java.lang.ref.ReferenceQueue;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Vector;
import static sun.java2d.marlin.MarlinConst.logUnsafeMalloc;
-import sun.awt.util.ThreadGroupUtils;
import jdk.internal.misc.Unsafe;
+import jdk.internal.ref.CleanerFactory;
/**
*
@@ -45,36 +40,9 @@
// size of int / float
static final int SIZE_INT;
- // RendererContext reference queue
- private static final ReferenceQueue<Object> rdrQueue
- = new ReferenceQueue<Object>();
- // reference list
- private static final Vector<OffHeapReference> refList
- = new Vector<OffHeapReference>(32);
-
static {
unsafe = Unsafe.getUnsafe();
SIZE_INT = Unsafe.ARRAY_INT_INDEX_SCALE;
-
- // Mimics Java2D Disposer:
- AccessController.doPrivileged(
- (PrivilegedAction<Void>) () -> {
- /*
- * The thread must be a member of a thread group
- * which will not get GCed before VM exit.
- * Make its parent the top-level thread group.
- */
- final ThreadGroup rootTG
- = ThreadGroupUtils.getRootThreadGroup();
- final Thread t = new Thread(rootTG, new OffHeapDisposer(),
- "MarlinRenderer Disposer");
- t.setContextClassLoader(null);
- t.setDaemon(true);
- t.setPriority(Thread.MAX_PRIORITY);
- t.start();
- return null;
- }
- );
}
/* members */
@@ -89,12 +57,12 @@
this.used = 0;
if (logUnsafeMalloc) {
MarlinUtils.logInfo(System.currentTimeMillis()
- + ": OffHeapArray.allocateMemory = "
+ + ": OffHeapArray.allocateMemory = "
+ len + " to addr = " + this.address);
}
- // Create the phantom reference to ensure freeing off-heap memory:
- refList.add(new OffHeapReference(parent, this));
+ // Register a cleaning function to ensure freeing off-heap memory:
+ CleanerFactory.cleaner().register(parent, () -> this.free());
}
/*
@@ -117,7 +85,7 @@
unsafe.freeMemory(this.address);
if (logUnsafeMalloc) {
MarlinUtils.logInfo(System.currentTimeMillis()
- + ": OffHeapEdgeArray.free = "
+ + ": OffHeapArray.freeMemory = "
+ this.length
+ " at addr = " + this.address);
}
@@ -126,41 +94,4 @@
void fill(final byte val) {
unsafe.setMemory(this.address, this.length, val);
}
-
- static final class OffHeapReference extends PhantomReference<Object> {
-
- private final OffHeapArray array;
-
- OffHeapReference(final Object parent, final OffHeapArray edges) {
- super(parent, rdrQueue);
- this.array = edges;
- }
-
- void dispose() {
- // free off-heap blocks
- this.array.free();
- }
- }
-
- static final class OffHeapDisposer implements Runnable {
- @Override
- public void run() {
- final Thread currentThread = Thread.currentThread();
- OffHeapReference ref;
-
- // check interrupted:
- for (; !currentThread.isInterrupted();) {
- try {
- ref = (OffHeapReference)rdrQueue.remove();
- ref.dispose();
-
- refList.remove(ref);
-
- } catch (InterruptedException ie) {
- MarlinUtils.logException("OffHeapDisposer interrupted:",
- ie);
- }
- }
- }
- }
}
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java Thu Jan 14 23:14:01 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java Wed Jan 20 22:53:26 2016 +0100
@@ -514,7 +514,7 @@
Renderer(final RendererContext rdrCtx) {
this.rdrCtx = rdrCtx;
- this.edges = new OffHeapArray(rdrCtx, INITIAL_EDGES_CAPACITY); // 96K
+ this.edges = new OffHeapArray(rdrCtx.cleanerObj, INITIAL_EDGES_CAPACITY); // 96K
this.curve = rdrCtx.curve;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java Thu Jan 14 23:14:01 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java Wed Jan 20 22:53:26 2016 +0100
@@ -68,6 +68,8 @@
* @see MarlinRenderingEngine#REF_TYPE
*/
final Object reference;
+ // Smallest object used as Cleaner's parent reference
+ final Object cleanerObj = new Object();
// dirty flag indicating an exception occured during pipeline in pathTo()
boolean dirty = false;
// dynamic array caches kept using weak reference (low memory footprint)
@@ -187,10 +189,10 @@
if (USE_CACHE_HARD_REF) {
// update hard reference:
hardRefArrayCaches = holder;
+ } else {
+ // update weak reference:
+ refArrayCaches = new WeakReference<ArrayCachesHolder>(holder);
}
-
- // update weak reference:
- refArrayCaches = new WeakReference<ArrayCachesHolder>(holder);
}
}
return holder;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java Thu Jan 14 23:14:01 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java Wed Jan 20 22:53:26 2016 +0100
@@ -27,7 +27,7 @@
public final class Version {
- private static final String version = "marlin-0.7.2-Unsafe-OpenJDK";
+ private static final String version = "marlin-0.7.3-Unsafe-OpenJDK";
public static String getVersion() {
return version;