Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java
38828 views
/*1* Copyright (c) 1998, 2013, 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 411643725* @summary Distributed Garbage Collector Memory Leak26*27* @author Laird Dornin28*29* @library ../../testlibrary30* @build TestLibrary CheckLeaseLeak_Stub LeaseLeakClient LeaseLeak31* @run main/othervm/timeout=240 CheckLeaseLeak32*33*/3435/**36* A bug in sun.rmi.transport.DGCImp.checkLeases() results in memory37* leak of LeaseInfo objects.38*39* In order to verify that this problem no longer exists, we create a40* remote object and a serveral clients in different VMs. The clients41* call a remote method on an exported object. This will cause the rmi42* runtime to create several references (all with different vmids) to43* the remote object. Each vmid needs a seperate LeaseInfo object in44* the object table target DGCImpl.leaseTable. If the leak is fixed,45* the leaseTable field will contain no objects. We use reflection to46* find the number of objects contained in this table.47*/4849import java.rmi.*;50import java.rmi.server.*;51import sun.rmi.transport.*;52import sun.rmi.*;53import java.util.Map;54import java.io.*;55import java.lang.reflect.*;56import java.rmi.registry.*;5758public class CheckLeaseLeak extends UnicastRemoteObject implements LeaseLeak {59public CheckLeaseLeak() throws RemoteException { }60public void ping () throws RemoteException { }6162/**63* Id to fake the DGC_ID, so we can later get a reference to the64* DGCImpl in the object table.65*/66private final static int DGC_ID = 2;6768private final static int ITERATIONS = 10;69private final static int numberPingCalls = 0;70private final static int CHECK_INTERVAL = 400;71private final static int LEASE_VALUE = 20;7273public static void main (String[] args) {74CheckLeaseLeak leakServer = null;75int numLeft =0;7677/*78* we want DGC to collect leases *quickly*79* decrease the lease check interval80*/81TestLibrary.setInteger("sun.rmi.dgc.checkInterval",82CHECK_INTERVAL);83TestLibrary.setInteger("java.rmi.dgc.leaseValue",84LEASE_VALUE);8586try {87Registry registry =88TestLibrary.createRegistryOnUnusedPort();89int registryPort = TestLibrary.getRegistryPort(registry);9091leakServer = new CheckLeaseLeak();92registry.rebind("/LeaseLeak", leakServer);9394/* create a bunch of clients in a *different* vm */95for (int i = 0 ; i < ITERATIONS ; i ++ ) {96System.err.println("Created client: " + i);9798JavaVM jvm = new JavaVM("LeaseLeakClient",99" -Djava.security.policy=" +100TestParams.defaultPolicy +101" -Drmi.registry.port=" +102registryPort,103"");104105if (jvm.execute() != 0) {106TestLibrary.bomb("Client process failed");107}108}109numLeft = getDGCLeaseTableSize();110Thread.sleep(3000);111112} catch(Exception e) {113TestLibrary.bomb("CheckLeaseLeak Error: ", e);114} finally {115if (leakServer != null) {116TestLibrary.unexport(leakServer);117leakServer = null;118}119}120121/* numLeft should be 2 - if 11 there is a problem. */122if (numLeft > 2) {123TestLibrary.bomb("Too many objects in DGCImpl.leaseTable: "+124numLeft);125} else {126System.err.println("Check leaseInfo leak passed with " +127numLeft128+ " object(s) in the leaseTable");129}130}131132/**133* Obtain a reference to the main DGCImpl via reflection. Extract134* the DGCImpl using the ObjectTable and the well known ID of the135* DGCImpl.136*/137private static int getDGCLeaseTableSize () {138int numLeaseInfosLeft = 0;139140/**141* Will eventually be set to point at the leaseTable inside142* DGCImpl.143*/144Map leaseTable = null;145final Remote[] dgcImpl = new Remote[1];146Field f;147148try {149f = (Field) java.security.AccessController.doPrivileged150(new java.security.PrivilegedExceptionAction() {151public Object run() throws Exception {152153ObjID dgcID = new ObjID(DGC_ID);154155/*156* Construct an ObjectEndpoint containing DGC's157* ObjID.158*/159Class oeClass =160Class.forName("sun.rmi.transport.ObjectEndpoint");161Class[] constrParams =162new Class[]{ ObjID.class, Transport.class };163Constructor oeConstructor =164oeClass.getDeclaredConstructor(constrParams);165oeConstructor.setAccessible(true);166Object oe =167oeConstructor.newInstance(168new Object[]{ dgcID, null });169170/*171* Get Target that contains DGCImpl in ObjectTable172*/173Class objTableClass =174Class.forName("sun.rmi.transport.ObjectTable");175Class getTargetParams[] = new Class[] { oeClass };176Method objTableGetTarget =177objTableClass.getDeclaredMethod("getTarget",178getTargetParams);179objTableGetTarget.setAccessible(true);180Target dgcTarget = (Target)181objTableGetTarget.invoke(null, new Object[]{ oe });182183/* get the DGCImpl from its Target */184Method targetGetImpl =185dgcTarget.getClass().getDeclaredMethod186("getImpl", null);187targetGetImpl.setAccessible(true);188dgcImpl[0] =189(Remote) targetGetImpl.invoke(dgcTarget, null);190191/* Get the lease table from the DGCImpl. */192Field reflectedLeaseTable =193dgcImpl[0].getClass().getDeclaredField194("leaseTable");195reflectedLeaseTable.setAccessible(true);196197return reflectedLeaseTable;198}199});200201/**202* This is the leaseTable that will fill up with LeaseInfo203* objects if the LeaseInfo memory leak is not fixed.204*/205leaseTable = (Map) f.get(dgcImpl[0]);206207numLeaseInfosLeft = leaseTable.size();208209} catch(Exception e) {210if (e instanceof java.security.PrivilegedActionException)211e = ((java.security.PrivilegedActionException) e).212getException();213TestLibrary.bomb(e);214}215216return numLeaseInfosLeft;217}218}219220221