Path: blob/master/test/jdk/com/sun/crypto/provider/KeyFactory/TestProviderLeak.java
41159 views
/*1* Copyright (c) 2005, 2016, 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/*24* @test25* @bug 6578538 802762426* @summary com.sun.crypto.provider.SunJCE instance leak using KRB5 and27* LoginContext28* @author Brad Wetmore29*30* @run main/othervm -Xmx20m TestProviderLeak31*32*/3334/*35* We force the leak to become a problem by eating up most JVM free memory.36* In current runs on a server and client machine, it took roughly 50-15037* iterations to have the memory leak or time-out shut down other operations.38* It complained about "JCE cannot authenticate the provider SunJCE" or timed39* out.40*/4142import javax.crypto.*;43import javax.crypto.spec.*;4445import java.util.*;46import java.util.concurrent.*;4748public class TestProviderLeak {49private static final int MB = 1024 * 1024;50// Currently, 3MB heap size is reserved for running testing iterations.51// It is tweaked to make sure the test quickly triggers the memory leak52// or throws out TimeoutException.53private static final int RESERVATION = 3;54// The maximum time, 5 seconds, to wait for each iteration.55private static final int TIME_OUT;56static {57int timeout = 5;58try {59double timeoutFactor = Double.parseDouble(60System.getProperty("test.timeout.factor", "1.0"));61timeout = (int) (timeout * timeoutFactor);62} catch (Exception e) {63System.out.println("Warning: " + e);64}65TIME_OUT = timeout;66System.out.println("Timeout for each iteration is "67+ TIME_OUT + " seconds");68}6970private static Deque<byte []> eatupMemory() throws Exception {71dumpMemoryStats("Before memory allocation");7273Deque<byte []> data = new ArrayDeque<byte []>();74boolean hasException = false;75while (!hasException) {76byte [] megaByte;77try {78megaByte = new byte [MB];79data.add(megaByte);80} catch (OutOfMemoryError e) {81megaByte = null; // Free memory ASAP8283int size = data.size();8485for (int j = 0; j < RESERVATION && !data.isEmpty(); j++) {86data.removeLast();87}88System.gc();89hasException = true;90System.out.println("OOME is thrown when allocating "91+ size + "MB memory.");92}93}94dumpMemoryStats("After memory allocation");9596return data;97}9899private static void dumpMemoryStats(String s) throws Exception {100Runtime rt = Runtime.getRuntime();101System.out.println(s + ":\t"102+ rt.freeMemory() + " bytes free");103}104105public static void main(String [] args) throws Exception {106// Prepare the test107final SecretKeyFactory skf =108SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1", "SunJCE");109final PBEKeySpec pbeKS = new PBEKeySpec(110"passPhrase".toCharArray(), new byte [] { 0 }, 5, 512);111112ExecutorService executor = Executors.newSingleThreadExecutor();113Callable<SecretKey> task = new Callable<SecretKey>() {114@Override115public SecretKey call() throws Exception {116return skf.generateSecret(pbeKS);117}118};119120// Eat up memory121Deque<byte []> dummyData = eatupMemory();122assert (dummyData != null);123124// Start testing iteration125try {126for (int i = 0; i <= 1000; i++) {127if ((i % 20) == 0) {128// Calling gc() isn't dependable, but doesn't hurt.129// Gives better output in leak cases.130System.gc();131dumpMemoryStats("Iteration " + i);132}133134Future<SecretKey> future = executor.submit(task);135136try {137future.get(TIME_OUT, TimeUnit.SECONDS);138} catch (Exception e) {139dumpMemoryStats("\nException seen at iteration " + i);140throw e;141}142}143} finally {144// JTReg will time out after two minutes. Proactively release145// the memory to avoid JTReg time-out situation.146dummyData = null;147System.gc();148dumpMemoryStats("Memory dereference");149executor.shutdownNow();150}151}152}153154155