| /* |
| * Copyright (c) 2002, 2018, 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 |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /* |
| * @test |
| * @key stress gc |
| * |
| * @summary converted from VM Testbase gc/gctests/LoadUnloadGC. |
| * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent, monitoring] |
| * VM Testbase readme: |
| * In this test a 1000 classes are loaded and unloaded in a loop. |
| * Class0 gets loaded which results in Class1 getting loaded and so on all |
| * the way uptill class1000. The classes should be unloaded whenever a |
| * garbage collection takes place because their classloader is made unreachable |
| * at the end of the each loop iteration. The loop is repeated 1000 times. |
| * |
| * @requires vm.opt.final.ClassUnloading |
| * @library /vmTestbase |
| * /test/lib |
| * @run driver jdk.test.lib.FileInstaller . . |
| * @build nsk.share.gc.ClassChain |
| * @run main/othervm |
| * -XX:MaxMetaspaceSize=64M |
| * -XX:MetaspaceSize=32M |
| * -XX:CompressedClassSpaceSize=32M |
| * gc.gctests.LoadUnloadGC.LoadUnloadGC |
| */ |
| |
| package gc.gctests.LoadUnloadGC; |
| |
| import nsk.share.test.*; |
| import nsk.share.gc.*; |
| import nsk.share.classload.ClassPathNonDelegatingClassLoader; |
| import vm.share.monitoring.MemoryPoolFinder; |
| |
| import java.io.*; |
| import java.util.*; |
| import java.lang.management.MemoryPoolMXBean; |
| |
| /** |
| * This test checks that classes are unloaded when loaded multiple times |
| * with custom class loader. |
| */ |
| public class LoadUnloadGC extends ThreadedGCTest { |
| private final String className = "nsk.share.gc.ClassChain"; |
| private int [] memory_reserve = new int[10000]; |
| |
| private class Loader implements Runnable { |
| private Class class_zero_class; |
| private Object class_zero_object; |
| |
| public void run() { |
| try { |
| // load Class0 and instantiate it |
| // This will cause all thousand classes to get loaded |
| ClassPathNonDelegatingClassLoader loader = new ClassPathNonDelegatingClassLoader(); |
| class_zero_class = loader.loadClass(className, false); |
| class_zero_object = class_zero_class.newInstance(); |
| // Set all references to null . This should cause a GC |
| // which should forces an unloading of all these |
| // unreferenced classes. |
| class_zero_class = null; |
| class_zero_object = null; |
| loader = null; |
| } catch (ClassNotFoundException e) { |
| throw new RuntimeException(e); |
| } catch (InstantiationException e) { |
| throw new RuntimeException(e); |
| } catch (IllegalAccessException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| } |
| |
| protected Runnable createRunnable(int i) { |
| return new Loader(); |
| } |
| |
| protected static int getThreadCount() { |
| MemoryPoolMXBean bean = MemoryPoolFinder.findPool(MemoryPoolFinder.METASPACE); |
| ClassPathNonDelegatingClassLoader loader = new ClassPathNonDelegatingClassLoader(); |
| long used = bean.getUsage().getUsed(); |
| long free = 0; |
| int classesCount = 1000; |
| int classesToLoad = 10; |
| if(bean.getUsage().getMax() == -1) { |
| throw new RuntimeException("Metaspace size should be limited for this test."); |
| } |
| try { |
| for(int i = 1; i <= classesToLoad; i++) { |
| loader.loadClass("nsk.share.gc.Class"+i); |
| } |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| used = bean.getUsage().getUsed() - used; |
| free = (bean.getUsage().getMax() - bean.getUsage().getUsed())/2; |
| return Math.min((int)(0.95*free/(classesCount/classesToLoad*used)), |
| Runtime.getRuntime().availableProcessors()); |
| } |
| |
| public static void main(String args[]) { |
| int threadCount = getThreadCount(); |
| if (Arrays.binarySearch(args,"-t") < 0) { |
| args = Arrays.copyOf(args,args.length+2); |
| args[args.length-2] = "-t"; |
| args[args.length-1] = Integer.toString(threadCount); |
| } |
| GC.runTest(new LoadUnloadGC(), args); |
| } |
| } |