Path: blob/master/test/hotspot/jtreg/vmTestbase/gc/gctests/StringInternSyncWithGC/StringInternSyncWithGC.java
41155 views
/*1* Copyright (c) 2011, 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/*24* @test25* @key stress randomness26*27* @summary converted from VM Testbase gc/gctests/StringInternSyncWithGC.28* VM Testbase keywords: [gc, stress, stressopt, feature_perm_removal_jdk7, nonconcurrent]29* VM Testbase readme:30* The test verifies that String.intern is correctly synchronized with GC.31* Test interns and drop the same strings in different threads and provokes GC.32* Additionally test creates weak/soft references to interned strings.33* Test fails if any string object is inaccessible.34*35* @library /vmTestbase36* /test/lib37* @run main/othervm38* -Xlog:gc:gc.log39* gc.gctests.StringInternSyncWithGC.StringInternSyncWithGC40* -ms low41* -memUsage 342* -appTimeout 3043* -capacityVerPart 244*/4546package gc.gctests.StringInternSyncWithGC;4748import java.util.ArrayList;49import java.util.List;5051import nsk.share.gc.*;52import nsk.share.gc.gp.MemoryStrategy;53import nsk.share.gc.gp.MemoryStrategyAware;54import nsk.share.gc.gp.string.RandomStringProducer;55import nsk.share.test.ExecutionController;5657public class StringInternSyncWithGC extends ThreadedGCTest implements MemoryStrategyAware {5859// Maximum size of one string60// Depends from all size and memory strategy61private int maxStringSize;62private MemoryStrategy memoryStrategy;63private final int memUsageFactor;64private final long endTimeCapacityVer;6566// The list of strings which are interned during iteration67private final List<String> stringsToIntern = new ArrayList();68private final RandomStringProducer gp = new RandomStringProducer();6970public StringInternSyncWithGC(int memUsage, long endTimeCapVer) {71memUsageFactor = memUsage;72endTimeCapacityVer = endTimeCapVer;73}7475@Override76public void setMemoryStrategy(MemoryStrategy memoryStrategy) {77this.memoryStrategy = memoryStrategy;78}7980/**81* Verify that we could use certain amount of memory.82*/83private boolean verifyInternedStringCapacity(long initialSize) {84long currentSize = 0;85final int STEP = 1000;86int iter = 0;87char[] template = new char[(int) (initialSize / STEP)];8889List<String> tmpList = new ArrayList<>(STEP);90try {91while (currentSize <= initialSize) {92if (endTimeCapacityVer < System.currentTimeMillis()) {93log.debug("Too long to verify interned string capacity");94log.debug("Silently pass.");95return false;96}97template[iter]++;98if (++iter == template.length) {99iter = 0;100}101String str = new String(template);102tmpList.add(str.intern());103currentSize += str.length() * 2; //each char costs 2 bytes104}105} catch (OutOfMemoryError oome) {106log.debug("It is not possible to allocate " + initialSize + " size of interned string.");107log.debug("Silently pass.");108return false;109}110return true;111}112113@Override114public void run() {115long size = runParams.getTestMemory() / memUsageFactor;116if (!verifyInternedStringCapacity(size)) {117return;118}119// Approximate size occupied by all interned strings120long sizeOfAllInternedStrings = size / 2;121maxStringSize = (int) (sizeOfAllInternedStrings / memoryStrategy.getSize(sizeOfAllInternedStrings, Memory.getObjectExtraSize()));122// Each thread keeps reference to each created string.123long extraConsumption = runParams.getNumberOfThreads() * Memory.getReferenceSize();124log.debug("The overall size of interned strings : " + sizeOfAllInternedStrings / (1024 * 1024) + "M");125log.debug("The count of interned strings : " + sizeOfAllInternedStrings / (maxStringSize + extraConsumption));126for (long currentSize = 0; currentSize <= sizeOfAllInternedStrings;127currentSize += maxStringSize + extraConsumption) {128stringsToIntern.add(gp.create(maxStringSize));129}130super.run();131}132133@Override134protected Runnable createRunnable(int threadId) {135return new StringGenerator(threadId, this);136}137138public static void main(String[] args) {139int appTimeout = -1;140int memUsageFactor = 1;141// Part of time that function verifyInternedStringCapacity can take. Time = Application_Timeout / capacityVerTimePart142double capacityVerPart = 2;143for (int i = 0; i < args.length; ++i) {144switch (args[i]) {145case "-memUsage":146memUsageFactor = Integer.parseInt(args[i + 1]);147break;148case "-capacityVerPart":149capacityVerPart = Double.parseDouble(args[i + 1]);150break;151case "-appTimeout":152appTimeout = Integer.parseInt(args[i + 1]);153break;154default:155}156}157if (appTimeout == -1) {158throw new IllegalArgumentException("Specify -appTimeout.");159}160long endTimeCapacityVer = System.currentTimeMillis() + (long) (appTimeout / capacityVerPart * 60000);161GC.runTest(new StringInternSyncWithGC(memUsageFactor, endTimeCapacityVer), args);162}163164protected List<String> getStringsToIntern() {165return stringsToIntern;166}167168protected int getNumberOfThreads() {169return runParams.getNumberOfThreads();170}171172protected RandomStringProducer getGarbageProducer() {173return gp;174}175176protected int getMaxStringSize() {177return maxStringSize;178}179180protected ExecutionController getExecController() {181return getExecutionController();182}183}184185186