< prev index next >

test/jdk/java/io/FileInputStream/UnreferencedFISClosesFd.java

Print this page
rev 52044 : 8192939: Remove Finalize methods from FileInputStream and FileOutputStream

*** 60,78 **** * - Subclasses finalize overridden - cleaner cleanup * - Subclasses finalize and close overridden - AltFinalizer cleanup */ public class UnreferencedFISClosesFd { - enum CleanupType { - CLOSE, // Cleanup is handled via calling close - CLEANER} // Cleanup is handled via Cleaner - static final String FILE_NAME = "empty.txt"; /** * Subclass w/ no overrides; not finalize or close. ! * Cleanup should be via the Cleaner (not close). */ public static class StreamOverrides extends FileInputStream { protected final AtomicInteger closeCounter; --- 60,74 ---- * - Subclasses finalize overridden - cleaner cleanup * - Subclasses finalize and close overridden - AltFinalizer cleanup */ public class UnreferencedFISClosesFd { static final String FILE_NAME = "empty.txt"; /** * Subclass w/ no overrides; not finalize or close. ! * Cleanup should be via the Cleaner. */ public static class StreamOverrides extends FileInputStream { protected final AtomicInteger closeCounter;
*** 86,96 **** } } /** * Subclass overrides close. ! * Cleanup should be via AltFinalizer calling close(). */ public static class StreamOverridesClose extends StreamOverrides { public StreamOverridesClose(String name) throws FileNotFoundException { super(name); --- 82,92 ---- } } /** * Subclass overrides close. ! * Cleanup should be via the Cleaner. */ public static class StreamOverridesClose extends StreamOverrides { public StreamOverridesClose(String name) throws FileNotFoundException { super(name);
*** 102,121 **** } } /** * Subclass overrides finalize. ! * Cleanup should be via the Cleaner (not close). */ public static class StreamOverridesFinalize extends StreamOverrides { public StreamOverridesFinalize(String name) throws FileNotFoundException { super(name); } @SuppressWarnings({"deprecation","removal"}) ! protected void finalize() throws IOException { super.finalize(); } } /** --- 98,117 ---- } } /** * Subclass overrides finalize. ! * Cleanup should be via the Cleaner. */ public static class StreamOverridesFinalize extends StreamOverrides { public StreamOverridesFinalize(String name) throws FileNotFoundException { super(name); } @SuppressWarnings({"deprecation","removal"}) ! protected void finalize() throws IOException, Throwable { super.finalize(); } } /**
*** 127,137 **** public StreamOverridesFinalizeClose(String name) throws FileNotFoundException { super(name); } @SuppressWarnings({"deprecation","removal"}) ! protected void finalize() throws IOException { super.finalize(); } } /** --- 123,133 ---- public StreamOverridesFinalizeClose(String name) throws FileNotFoundException { super(name); } @SuppressWarnings({"deprecation","removal"}) ! protected void finalize() throws IOException, Throwable { super.finalize(); } } /**
*** 147,165 **** FileUtils.listFileDescriptors(System.out); long fdCount0 = getFdCount(); int failCount = 0; ! failCount += test(new FileInputStream(name), CleanupType.CLEANER); ! failCount += test(new StreamOverrides(name), CleanupType.CLEANER); ! failCount += test(new StreamOverridesClose(name), CleanupType.CLOSE); ! failCount += test(new StreamOverridesFinalize(name), CleanupType.CLEANER); ! failCount += test(new StreamOverridesFinalizeClose(name), CleanupType.CLOSE); if (failCount > 0) { throw new AssertionError("Failed test count: " + failCount); } --- 143,161 ---- FileUtils.listFileDescriptors(System.out); long fdCount0 = getFdCount(); int failCount = 0; ! failCount += test(new FileInputStream(name)); ! failCount += test(new StreamOverrides(name)); ! failCount += test(new StreamOverridesClose(name)); ! failCount += test(new StreamOverridesFinalize(name)); ! failCount += test(new StreamOverridesFinalizeClose(name)); if (failCount > 0) { throw new AssertionError("Failed test count: " + failCount); }
*** 178,188 **** return (mxBean instanceof UnixOperatingSystemMXBean) ? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount() : -1L; } ! private static int test(FileInputStream fis, CleanupType cleanType) throws Exception { try { System.out.printf("%nTesting %s%n", fis.getClass().getName()); // Prepare to wait for FIS to be reclaimed --- 174,184 ---- return (mxBean instanceof UnixOperatingSystemMXBean) ? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount() : -1L; } ! private static int test(FileInputStream fis) throws Exception { try { System.out.printf("%nTesting %s%n", fis.getClass().getName()); // Prepare to wait for FIS to be reclaimed
*** 197,235 **** Field fdField = FileDescriptor.class.getDeclaredField("fd"); fdField.setAccessible(true); int ffd = fdField.getInt(fd); - Field altFinalizerField = FileInputStream.class.getDeclaredField("altFinalizer"); - altFinalizerField.setAccessible(true); - Object altFinalizer = altFinalizerField.get(fis); - if ((altFinalizer != null) ^ (cleanType == CleanupType.CLOSE)) { - throw new RuntimeException("Unexpected AltFinalizer: " + altFinalizer - + ", for " + cleanType); - } - Field cleanupField = FileDescriptor.class.getDeclaredField("cleanup"); cleanupField.setAccessible(true); Object cleanup = cleanupField.get(fd); ! System.out.printf(" cleanup: %s, alt: %s, ffd: %d, cf: %s%n", ! cleanup, altFinalizer, ffd, cleanupField); ! if ((cleanup != null) ^ (cleanType == CleanupType.CLEANER)) { ! throw new Exception("unexpected cleanup: " ! + cleanup + ", for " + cleanType); } ! if (cleanup != null) { WeakReference<Object> cleanupWeak = new WeakReference<>(cleanup, queue); pending.add(cleanupWeak); System.out.printf(" fdWeak: %s%n msWeak: %s%n cleanupWeak: %s%n", fdWeak, msWeak, cleanupWeak); - } - if (altFinalizer != null) { - WeakReference<Object> altFinalizerWeak = new WeakReference<>(altFinalizer, queue); - pending.add(altFinalizerWeak); - System.out.printf(" fdWeak: %s%n msWeak: %s%n altFinalizerWeak: %s%n", - fdWeak, msWeak, altFinalizerWeak); - } AtomicInteger closeCounter = fis instanceof StreamOverrides ? ((StreamOverrides)fis).closeCounter() : null; Reference<?> r; --- 193,214 ---- Field fdField = FileDescriptor.class.getDeclaredField("fd"); fdField.setAccessible(true); int ffd = fdField.getInt(fd); Field cleanupField = FileDescriptor.class.getDeclaredField("cleanup"); cleanupField.setAccessible(true); Object cleanup = cleanupField.get(fd); ! System.out.printf(" cleanup: %s, ffd: %d, cf: %s%n", cleanup, ffd, cleanupField); ! if (cleanup == null) { ! throw new RuntimeException("cleanup should not be null"); } ! WeakReference<Object> cleanupWeak = new WeakReference<>(cleanup, queue); pending.add(cleanupWeak); System.out.printf(" fdWeak: %s%n msWeak: %s%n cleanupWeak: %s%n", fdWeak, msWeak, cleanupWeak); AtomicInteger closeCounter = fis instanceof StreamOverrides ? ((StreamOverrides)fis).closeCounter() : null; Reference<?> r;
*** 241,272 **** pending.remove(r); } else { fis = null; fd = null; cleanup = null; - altFinalizer = null; System.gc(); // attempt to reclaim them } } Reference.reachabilityFence(fd); Reference.reachabilityFence(fis); Reference.reachabilityFence(cleanup); - Reference.reachabilityFence(altFinalizer); // Confirm the correct number of calls to close depending on the cleanup type - switch (cleanType) { - case CLEANER: if (closeCounter != null && closeCounter.get() > 0) { ! throw new RuntimeException("Close should not have been called: count: " ! + closeCounter); ! } ! break; ! case CLOSE: ! if (closeCounter == null || closeCounter.get() == 0) { ! throw new RuntimeException("Close should have been called: count: 0"); ! } ! break; } } catch (Exception ex) { ex.printStackTrace(System.out); return 1; } --- 220,239 ---- pending.remove(r); } else { fis = null; fd = null; cleanup = null; System.gc(); // attempt to reclaim them } } Reference.reachabilityFence(fd); Reference.reachabilityFence(fis); Reference.reachabilityFence(cleanup); // Confirm the correct number of calls to close depending on the cleanup type if (closeCounter != null && closeCounter.get() > 0) { ! throw new RuntimeException("Close should not have been called: count: " + closeCounter); } } catch (Exception ex) { ex.printStackTrace(System.out); return 1; }
< prev index next >