Path: blob/master/test/jdk/java/io/RandomAccessFile/UnreferencedRAFClosesFd.java
41149 views
/*1* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.File;24import java.io.FileDescriptor;25import java.io.FileNotFoundException;26import java.io.IOException;27import java.io.RandomAccessFile;28import java.lang.management.ManagementFactory;29import java.lang.management.OperatingSystemMXBean;30import java.lang.ref.Cleaner;31import java.lang.ref.Reference;32import java.lang.ref.ReferenceQueue;33import java.lang.ref.WeakReference;34import java.lang.reflect.Field;35import java.nio.file.Path;36import java.util.ArrayDeque;37import java.util.HashSet;3839import com.sun.management.UnixOperatingSystemMXBean;4041import jdk.test.lib.util.FileUtils;4243/**44* @test45* @bug 808022546* @library /test/lib47* @build jdk.test.lib.util.FileUtils UnreferencedRAFClosesFd48* @modules java.base/java.io:open49* @summary Test to ensure that an unclosed and unreferenced RandomAccessFile closes the fd50* @run main/othervm UnreferencedRAFClosesFd51*/52public class UnreferencedRAFClosesFd {5354static final String FILE_NAME = "empty.txt";5556/* standalone interface */57public static void main(String argv[]) throws Exception {5859File inFile= new File(System.getProperty("test.dir", "."), FILE_NAME);60inFile.createNewFile();61inFile.deleteOnExit();6263FileUtils.listFileDescriptors(System.out);64long fdCount0 = getFdCount();6566String name = inFile.getPath();67RandomAccessFile raf;68try {69// raf is explicitly *not* closed to allow cleaner to work70raf = new RandomAccessFile(name, "rw");71} catch (FileNotFoundException e) {72System.out.println("Unexpected exception " + e);73throw(e);74}75FileDescriptor fd = raf.getFD();7677Field fdField = FileDescriptor.class.getDeclaredField("cleanup");78fdField.setAccessible(true);79Cleaner.Cleanable cleanup = (Cleaner.Cleanable)fdField.get(fd);8081// Prepare to wait for FOS, FD, Cleanup to be reclaimed82ReferenceQueue<Object> queue = new ReferenceQueue<>();83HashSet<Reference<?>> pending = new HashSet<>(3);84pending.add(new WeakReference<>(cleanup, queue));85pending.add(new WeakReference<>(raf, queue));86pending.add(new WeakReference<>(fd, queue));8788Reference<?> r;89while (((r = queue.remove(10L)) != null)90|| !pending.isEmpty()) {91System.out.printf("r: %s, pending: %d%n", r, pending.size());92if (r != null) {93pending.remove(r);94} else {95cleanup = null;96raf = null;97fd = null;98System.gc(); // attempt to reclaim the RAF, cleanup, and fd99}100}101102// Keep these variables in scope as gc roots103Reference.reachabilityFence(cleanup);104Reference.reachabilityFence(fd);105Reference.reachabilityFence(raf);106Reference.reachabilityFence(pending);107108// Check the final count of open file descriptors109long fdCount = getFdCount();110if (fdCount != fdCount0) {111System.out.printf("initial count of open file descriptors: %d%n", fdCount0);112System.out.printf("final count of open file descriptors: %d%n", fdCount);113FileUtils.listFileDescriptors(System.out);114}115}116117118// Get the count of open file descriptors, or -1 if not available119private static long getFdCount() {120OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean();121return (mxBean instanceof UnixOperatingSystemMXBean)122? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount()123: -1L;124}125}126127128