Path: blob/master/test/jdk/java/nio/channels/FileChannel/CleanerTest.java
41154 views
/*1* Copyright (c) 2017, 2020, 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*/2223/* @test24* @bug 814761525* @summary Test whether an unreferenced FileChannel is actually cleaned26* @requires (os.family == "linux") | (os.family == "mac") | (os.family == "aix")27* @library /test/lib28* @build jdk.test.lib.util.FileUtils CleanerTest29* @modules java.management java.base/sun.nio.ch:+open30* @run main/othervm CleanerTest31*/3233import com.sun.management.UnixOperatingSystemMXBean;34import java.lang.management.ManagementFactory;35import java.lang.management.OperatingSystemMXBean;36import java.lang.ref.PhantomReference;37import java.lang.ref.Reference;38import java.lang.ref.ReferenceQueue;39import java.lang.ref.PhantomReference;40import java.lang.ref.WeakReference;41import java.lang.reflect.Field;42import java.nio.channels.FileChannel;43import java.nio.file.Files;44import java.nio.file.Path;45import java.nio.file.Paths;46import java.nio.file.StandardOpenOption;47import java.util.HashSet;4849import jdk.test.lib.util.FileUtils;5051import sun.nio.ch.FileChannelImpl;5253public class CleanerTest {54public static void main(String[] args) throws Throwable {55OperatingSystemMXBean mxBean =56ManagementFactory.getOperatingSystemMXBean();57UnixOperatingSystemMXBean unixMxBean = null;58if (mxBean instanceof UnixOperatingSystemMXBean) {59unixMxBean = (UnixOperatingSystemMXBean)mxBean;60} else {61System.out.println("Non-Unix system: skipping test.");62return;63}6465FileUtils.listFileDescriptors(System.out);66long fdCount0 = unixMxBean.getOpenFileDescriptorCount();6768Path path = Paths.get(System.getProperty("test.dir", "."), "junk");69try {70FileChannel fc = FileChannel.open(path, StandardOpenOption.CREATE,71StandardOpenOption.READ, StandardOpenOption.WRITE);7273// Prepare to wait for Channel, FD and Cleaner to be reclaimed74ReferenceQueue<Object> refQueue = new ReferenceQueue<>();75HashSet<Reference<?>> pending = new HashSet<>();7677Reference<Object> fcRef = new PhantomReference<>(fc, refQueue);78pending.add(fcRef);7980Field fdField = FileChannelImpl.class.getDeclaredField("fd");81fdField.setAccessible(true);82Object fd = fdField.get(fc); // get the fd from the channel83WeakReference<Object> fdWeak = new WeakReference<>(fd, refQueue);84pending.add(fdWeak);8586Field closerField = FileChannelImpl.class.getDeclaredField("closer");87closerField.setAccessible(true);88Object closer = closerField.get(fc);89System.out.printf(" cleanup: %s, fd: %s, cf: %s%n", fc, fd, closer);9091if (closer != null) {92WeakReference<Object> closerWeak = new WeakReference<>(closer, refQueue);93pending.add(closerWeak);94System.out.printf(" closerWeak: %s%n", closerWeak);95}9697// Wait for all of the objects being tracked to be reclaimed;98// The test will timeout if they are not reclaimed within the jtreg timeout99Reference<?> r;100while (((r = refQueue.remove(1000L)) != null)101|| !pending.isEmpty()) {102System.out.printf(" r: %s, pending: %d%n", r, pending.size());103if (r != null) {104pending.remove(r);105} else {106fc = null;107fd = null;108closer = null;109System.gc(); // attempt to reclaim them110}111}112113Reference.reachabilityFence(fc);114Reference.reachabilityFence(fd);115Reference.reachabilityFence(closer);116117long fdCount = unixMxBean.getOpenFileDescriptorCount();118if (fdCount != fdCount0) {119// Add debugging info about file descriptor changes120System.out.printf("initial count of open file descriptors: %d%n", fdCount0);121System.out.printf("final count of open file descriptors: %d%n", fdCount);122FileUtils.listFileDescriptors(System.out);123}124} finally {125Files.delete(path);126}127}128}129130131