changeset 9746:e7dadf42aa35

8081317: [NEWTEST] documented GC ratio tuning and new size options should be covered by regression tests Reviewed-by: iignatyev, dfazunen
author mchernov
date Tue, 01 Sep 2015 21:38:07 +0300
parents d750cc39ed60
children 9a8f97037119
files src/share/vm/prims/whitebox.cpp test/gc/arguments/GCTypes.java test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java test/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java test/gc/arguments/TestNewRatioFlag.java test/gc/arguments/TestNewSizeFlags.java test/gc/arguments/TestSurvivorRatioFlag.java test/gc/arguments/TestTargetSurvivorRatioFlag.java test/testlibrary/jdk/test/lib/AllocationHelper.java test/testlibrary/jdk/test/lib/HeapRegionUsageTool.java
diffstat 10 files changed, 1842 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/prims/whitebox.cpp	Mon Sep 07 21:30:45 2015 +0400
+++ b/src/share/vm/prims/whitebox.cpp	Tue Sep 01 21:38:07 2015 +0300
@@ -55,6 +55,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/parallel/parallelScavengeHeap.inline.hpp"
+#include "gc/parallel/adjoiningGenerations.hpp"
 #endif // INCLUDE_ALL_GCS
 #if INCLUDE_NMT
 #include "services/mallocSiteTable.hpp"
@@ -296,6 +297,11 @@
   return p->size() * HeapWordSize;
 WB_END
 
+WB_ENTRY(jlong, WB_GetHeapSpaceAlignment(JNIEnv* env, jobject o))
+  size_t alignment = Universe::heap()->collector_policy()->space_alignment();
+  return (jlong)alignment;
+WB_END
+
 #if INCLUDE_ALL_GCS
 WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
   G1CollectedHeap* g1 = G1CollectedHeap::heap();
@@ -334,6 +340,17 @@
   return (jint)HeapRegion::GrainBytes;
 WB_END
 
+WB_ENTRY(jlong, WB_PSVirtualSpaceAlignment(JNIEnv* env, jobject o))
+  ParallelScavengeHeap* ps = ParallelScavengeHeap::heap();
+  size_t alignment = ps->gens()->virtual_spaces()->alignment();
+  return (jlong)alignment;
+WB_END
+
+WB_ENTRY(jlong, WB_PSHeapGenerationAlignment(JNIEnv* env, jobject o))
+  size_t alignment = ParallelScavengeHeap::heap()->generation_alignment();
+  return (jlong)alignment;
+WB_END
+
 WB_ENTRY(jobject, WB_G1AuxiliaryMemoryUsage(JNIEnv* env))
   ResourceMark rm(THREAD);
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
@@ -1332,6 +1349,7 @@
   {CC"getVMPageSize",                    CC"()I",                   (void*)&WB_GetVMPageSize     },
   {CC"getVMAllocationGranularity",       CC"()J",                   (void*)&WB_GetVMAllocationGranularity },
   {CC"getVMLargePageSize",               CC"()J",                   (void*)&WB_GetVMLargePageSize},
+  {CC"getHeapSpaceAlignment",            CC"()J",                   (void*)&WB_GetHeapSpaceAlignment},
   {CC"isClassAlive0",                    CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive      },
   {CC"parseCommandLine0",
       CC"(Ljava/lang/String;C[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
@@ -1356,6 +1374,8 @@
   {CC"g1StartConcMarkCycle",       CC"()Z",           (void*)&WB_G1StartMarkCycle  },
   {CC"g1AuxiliaryMemoryUsage", CC"()Ljava/lang/management/MemoryUsage;",
                                                       (void*)&WB_G1AuxiliaryMemoryUsage  },
+  {CC"psVirtualSpaceAlignment",CC"()J",               (void*)&WB_PSVirtualSpaceAlignment},
+  {CC"psHeapGenerationAlignment",CC"()J",             (void*)&WB_PSHeapGenerationAlignment},
 #endif // INCLUDE_ALL_GCS
 #if INCLUDE_NMT
   {CC"NMTMalloc",           CC"(J)J",                 (void*)&WB_NMTMalloc          },
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/arguments/GCTypes.java	Tue Sep 01 21:38:07 2015 +0300
@@ -0,0 +1,115 @@
+/*
+* Copyright (c) 2015, 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.
+*/
+
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Helper class with enum representation of GC types.
+ */
+public final class GCTypes {
+
+    private static <T extends GCType> T getCurrentGCType(Class<T> type) {
+        return ManagementFactory.getGarbageCollectorMXBeans().stream()
+                .map(bean -> getGCTypeByName(type, bean.getName()))
+                .filter(Objects::nonNull)
+                .findFirst()
+                .orElse(null);
+    }
+
+    private static <T extends GCType> T getGCTypeByName(Class<T> type, String name) {
+        return Arrays.stream(type.getEnumConstants())
+                .filter(e -> e.getGCName().equals(name))
+                .findFirst()
+                .orElse(null);
+    }
+
+    private static <T extends GCType> GarbageCollectorMXBean getGCBeanByType(Class<T> type) {
+        return ManagementFactory.getGarbageCollectorMXBeans().stream()
+                .filter(bean -> Arrays.stream(type.getEnumConstants())
+                        .filter(enumName -> enumName.getGCName().equals(bean.getName()))
+                        .findFirst()
+                        .isPresent()
+                )
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Helper interface used by GCTypes static methods
+     * to get gcTypeName field of *GCType classes.
+     */
+    private interface GCType {
+
+        String getGCName();
+    }
+
+    public static enum YoungGCType implements GCType {
+        DefNew("Copy"),
+        ParNew("ParNew"),
+        PSNew("PS Scavenge"),
+        G1("G1 Young Generation");
+
+        @Override
+        public String getGCName() {
+            return gcTypeName;
+        }
+        private final String gcTypeName;
+
+        private YoungGCType(String name) {
+            gcTypeName = name;
+        }
+
+        public static YoungGCType getYoungGCType() {
+            return GCTypes.getCurrentGCType(YoungGCType.class);
+        }
+
+        public static GarbageCollectorMXBean getYoungGCBean() {
+            return GCTypes.getGCBeanByType(YoungGCType.class);
+        }
+    }
+
+    public static enum OldGCType implements GCType {
+        Serial("MarkSweepCompact"),
+        CMS("ConcurrentMarkSweep"),
+        PSOld("PS MarkSweep"),
+        G1("G1 Old Generation");
+
+        private final String gcTypeName;
+
+        private OldGCType(String name) {
+            gcTypeName = name;
+        }
+
+        public static OldGCType getOldGCType() {
+            return GCTypes.getCurrentGCType(OldGCType.class);
+        }
+
+        @Override
+        public String getGCName() {
+            return gcTypeName;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java	Tue Sep 01 21:38:07 2015 +0300
@@ -0,0 +1,299 @@
+/*
+* Copyright (c) 2015, 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 TestMaxMinHeapFreeRatioFlags
+ * @key gc
+ * @summary Verify that heap size changes according to max and min heap free ratios.
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management
+ * @build TestMaxMinHeapFreeRatioFlags
+ * @run driver/timeout=240 TestMaxMinHeapFreeRatioFlags
+ */
+
+import java.util.LinkedList;
+import java.util.Arrays;
+import java.util.Collections;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Utils;
+import jdk.test.lib.HeapRegionUsageTool;
+import sun.misc.Unsafe;
+
+public class TestMaxMinHeapFreeRatioFlags {
+
+    public static final long M = 1024 * 1024;
+    public static final long MAX_HEAP_SIZE = 200 * M;
+    public static final long HEAP_SIZE = 10 * M;
+    public static final long MAX_NEW_SIZE = 20 * M;
+    public static final long NEW_SIZE = 5 * M;
+
+    public static void main(String args[]) throws Exception {
+        LinkedList<String> options = new LinkedList<>(
+                Arrays.asList(Utils.getFilteredTestJavaOpts("-XX:[^ ]*HeapFreeRatio","-XX:\\+ExplicitGCInvokesConcurrent"))
+        );
+
+        negativeTest(20, false, 10, true, options);
+        negativeTest(100, true, 0, false, options);
+        negativeTest(101, false, 50, false, options);
+        negativeTest(49, true, 102, true, options);
+        negativeTest(-1, false, 50, false, options);
+        negativeTest(50, true, -1, true, options);
+
+        positiveTest(10, false, 90, false, options);
+        positiveTest(10, true, 80, false, options);
+        positiveTest(20, false, 70, true, options);
+        positiveTest(25, true, 65, true, options);
+        positiveTest(40, false, 50, false, options);
+    }
+
+    /**
+     * Verify that heap size will be changed to conform
+     * min and max heap free ratios.
+     *
+     * @param minRatio value of MinHeapFreeRatio option
+     * @param useXminf used Xminf option instead of MinHeapFreeRatio
+     * @param maxRatio value of MaxHeapFreeRatio option
+     * @param useXmaxf used Xmaxf option instead of MaxHeapFreeRatio
+     * @param options additional options for JVM
+     */
+    public static void positiveTest(int minRatio, boolean useXminf,
+            int maxRatio, boolean useXmaxf,
+            LinkedList<String> options) throws Exception {
+
+        LinkedList<String> vmOptions = new LinkedList<>(options);
+        Collections.addAll(vmOptions,
+                (useXminf ? "-Xminf" + minRatio / 100.0 : "-XX:MinHeapFreeRatio=" + minRatio),
+                (useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio),
+                "-Xmx" + MAX_HEAP_SIZE,
+                "-Xms" + HEAP_SIZE,
+                "-XX:NewSize=" + NEW_SIZE,
+                "-XX:MaxNewSize=" + MAX_NEW_SIZE,
+                RatioVerifier.class.getName(),
+                Integer.toString(minRatio),
+                Integer.toString(maxRatio)
+        );
+
+        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+        analyzer.shouldHaveExitValue(0);
+    }
+
+    /**
+     * Verify that VM will fail to start with specified ratios.
+     *
+     * @param minRatio value of MinHeapFreeRatio option
+     * @param useXminf used Xminf option instead of MinHeapFreeRatio
+     * @param maxRatio value of MaxHeapFreeRatio option
+     * @param useXmaxf used Xmaxf option instead of MaxHeapFreeRatio
+     * @param options additional options for JVM
+     */
+    public static void negativeTest(int minRatio, boolean useXminf,
+            int maxRatio, boolean useXmaxf,
+            LinkedList<String> options) throws Exception {
+
+        LinkedList<String> vmOptions = new LinkedList<>(options);
+        Collections.addAll(vmOptions,
+                (useXminf ? "-Xminf" + minRatio / 100.0 : "-XX:MinHeapFreeRatio=" + minRatio),
+                (useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio),
+                "-version"
+        );
+        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+        analyzer.shouldHaveExitValue(1);
+        analyzer.shouldContain("Error: Could not create the Java Virtual Machine.");
+    }
+
+    /**
+     * RatioVerifier will be executed in the tested VM.
+     * It will check that real heap usage after collection lies between MinHeapFreeRatio and MaxHeapFreeRatio.
+     */
+    public static class RatioVerifier {
+
+        private static final Unsafe unsafe = Utils.getUnsafe();
+
+        // Size of byte array that will be allocated
+        public static final int CHUNK_SIZE = 1024;
+        // Length of byte array, that will be added to "garbage" list.
+        public static final int ARRAY_LENGTH = CHUNK_SIZE - Unsafe.ARRAY_BYTE_BASE_OFFSET;
+        // Amount of tries to force heap shrinking/expansion using GC
+        public static final int GC_TRIES = 10;
+
+        // Value that will be added/substracted from expected min/max heap free ratio
+        // during memory allocation to make sure that specified limit will be exceeded.
+        public static final double OVERLOAD = 0.05;
+        // Acceptable heap free ratio limit exceedance: verification will fail if
+        // actual ratio is lower than expected min heap free ratio - VARIANCE or
+        // higher than expected max heap free ratio + VARIANCE.
+        public static final double VARIANCE = 0.025;
+
+        public static LinkedList<Object> garbage = new LinkedList<>();
+
+        public static void main(String args[]) throws Exception {
+            if (args.length != 2) {
+                throw new IllegalArgumentException("Expected 2 args: <minRatio> <maxRatio>");
+            }
+            if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.PSOld) {
+                System.out.println("Test is not applicable to parallel GC");
+                return;
+            }
+
+            double minRatio = Integer.valueOf(args[0]) / 100.0;
+            double maxRatio = Integer.valueOf(args[1]) / 100.0;
+
+            long maxHeapSize = getMax();
+
+            // commit 0.5 of total heap size to have enough space
+            // to both shink and expand
+            while (getCommitted() < maxHeapSize / 2) {
+                garbage.add(new byte[ARRAY_LENGTH]);
+            }
+
+            forceGC();
+            // Verify that current heap free ratio lies between specified limits
+            verifyRatio(minRatio, maxRatio);
+
+            // Estimate how much memory we have to allocate to force expansion
+            long memoryToFill = (long) (getCommitted() * (1 - minRatio + OVERLOAD))
+                    - getUsed();
+
+            long previouslyCommitted = getCommitted();
+
+            while (memoryToFill > 0) {
+                garbage.add(new byte[CHUNK_SIZE]);
+                memoryToFill -= CHUNK_SIZE;
+            }
+
+            forceGC();
+            // Verify that after memory allocation heap free ratio is still conforming specified limits
+            verifyRatio(minRatio, maxRatio);
+            // Verify that heap was actually expanded
+            if (previouslyCommitted >= getCommitted()) {
+                throw new RuntimeException("Heap was not expanded.");
+            }
+
+            // Estimate how much memory we have to free to force shrinking
+            long memoryToFree = getUsed()
+                    - (long) (getCommitted() * (1 - maxRatio - OVERLOAD));
+
+            previouslyCommitted = getCommitted();
+
+            while (memoryToFree > 0 && garbage.size() > 0) {
+                garbage.remove(garbage.size() - 1);
+                memoryToFree -= CHUNK_SIZE;
+            }
+
+            forceGC();
+            // Verify that heap free ratio is still conforming specified limits
+            verifyRatio(minRatio, maxRatio);
+            // Verify that heap was actually shrinked
+            if (previouslyCommitted <= getCommitted()) {
+                throw new RuntimeException("Heap was not shrinked.");
+            }
+
+        }
+
+        public static void forceGC() {
+            for (int i = 0; i < GC_TRIES; i++) {
+                System.gc();
+                try {
+                    Thread.sleep(10);
+                } catch (InterruptedException ie) {
+                }
+            }
+        }
+
+        /**
+         * Verify that heap free ratio is conforming specified limits.
+         * Actual heap free ratio may be very close to one of specified limits,
+         * but exceed for more then VARIANCE.
+         * Verification will also pass if actual ratio is not conforming limits,
+         * but it is not possible to shrink/expand heap.
+         */
+        public static void verifyRatio(double minRatio, double maxRatio) {
+            double ratio = getHeapFreeRatio();
+            System.out.println(minRatio + " " + ratio + " " + maxRatio);
+            if (minRatio - ratio > VARIANCE
+                    && getCommitted() < getMax()) {
+                throw new RuntimeException("Current heap free ratio is lower than "
+                        + "MinHeapFreeRatio (" + ratio + " vs " + minRatio + ").");
+            }
+            if (ratio - maxRatio > VARIANCE
+                    && getUsed() > getInit()) {
+                throw new RuntimeException("Current heap free ratio is higher than "
+                        + "MaxHeapFreeRatio (" + ratio + " vs " + maxRatio + ").");
+            }
+        }
+
+        /*
+         * Obtain information about heap size.
+         *
+         * For G1 information summed up for all type of regions,
+         * because tested options affect overall heap sizing.
+         *
+         * For all other GCs return information only for old gen.
+         */
+        public static long getMax() {
+            return HeapRegionUsageTool.getOldUsage().getMax();
+        }
+
+        public static long getInit() {
+            if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.G1) {
+                return HeapRegionUsageTool.getEdenUsage().getInit()
+                        + HeapRegionUsageTool.getSurvivorUsage().getInit()
+                        + HeapRegionUsageTool.getOldUsage().getInit();
+            } else {
+                return HeapRegionUsageTool.getOldUsage().getInit();
+            }
+        }
+
+        public static long getUsed() {
+            if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.G1) {
+                return HeapRegionUsageTool.getEdenUsage().getUsed()
+                        + HeapRegionUsageTool.getSurvivorUsage().getUsed()
+                        + HeapRegionUsageTool.getOldUsage().getUsed();
+            } else {
+                return HeapRegionUsageTool.getOldUsage().getUsed();
+            }
+        }
+
+        public static long getCommitted() {
+            if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.G1) {
+                return HeapRegionUsageTool.getEdenUsage().getCommitted()
+                        + HeapRegionUsageTool.getSurvivorUsage().getCommitted()
+                        + HeapRegionUsageTool.getOldUsage().getCommitted();
+            } else {
+                return HeapRegionUsageTool.getOldUsage().getCommitted();
+            }
+        }
+
+        public static long getFree() {
+            return getCommitted() - getUsed();
+        }
+
+        public static double getHeapFreeRatio() {
+            return getFree() / (double) getCommitted();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java	Tue Sep 01 21:38:07 2015 +0300
@@ -0,0 +1,206 @@
+/*
+* Copyright (c) 2015, 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 TestMinAndInitialSurvivorRatioFlags
+ * @key gc
+ * @summary Verify that MinSurvivorRatio and InitialSurvivorRatio flags work
+ * @library /testlibrary /../../test/lib
+ * @modules java.base/sun.misc
+ *          java.management
+ * @build TestMinAndInitialSurvivorRatioFlags
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run driver TestMinAndInitialSurvivorRatioFlags
+ */
+
+import jdk.test.lib.AllocationHelper;
+import java.lang.management.MemoryUsage;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import jdk.test.lib.HeapRegionUsageTool;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+
+/* Test verifies that VM can start with any GC when MinSurvivorRatio and
+ * InitialSurvivorRatio flags passed and for Parallel GC it verifies that
+ * after start up survivor ratio equal to InitialSurvivorRatio value and
+ * that actual survivor ratio will never be less than MinSurvivorRatio.
+ */
+public class TestMinAndInitialSurvivorRatioFlags {
+
+    public static final long M = 1024 * 1024;
+    public static final long HEAP_SIZE = 200 * M;
+    public static final long NEW_SIZE = 100 * M;
+
+    public static void main(String args[]) throws Exception {
+        LinkedList<String> options = new LinkedList<>(
+                Arrays.asList(Utils.getFilteredTestJavaOpts("-XX:[^ ]*SurvivorRatio=[^ ]+"))
+        );
+
+        testSurvivorRatio(5, -1, -1, options, true);
+        testSurvivorRatio(10, -1, -1, options, true);
+        testSurvivorRatio(-1, 5, 3, options, true);
+        testSurvivorRatio(-1, 15, 3, options, true);
+        testSurvivorRatio(-1, 15, 3, options, false);
+        testSurvivorRatio(-1, 10, 10, options, true);
+        testSurvivorRatio(-1, 3, 15, options, true);
+        testSurvivorRatio(-1, 3, 15, options, false);
+    }
+
+    /**
+     * Test that MinSurvivorRatio and InitialSurvivorRatio flags work.
+     *
+     * @param survivorRatio value for -XX:SurvivorRatio option, omitted if negative
+     * @param initRatio value for -XX:InitialSurvivorRatio option, omitted if negative
+     * @param minRatio value for -XX:MinSurvivorRatio option, omitted if negative
+     * @param options additional options for VM
+     * @param useAdaptiveSizePolicy turn on or off UseAdaptiveSizePolicy option
+     */
+    public static void testSurvivorRatio(int survivorRatio,
+            int initRatio,
+            int minRatio,
+            LinkedList<String> options,
+            boolean useAdaptiveSizePolicy) throws Exception {
+
+        LinkedList<String> vmOptions = new LinkedList<>(options);
+        Collections.addAll(vmOptions,
+                "-Xbootclasspath/a:.",
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                "-XX:MaxNewSize=" + NEW_SIZE, "-XX:NewSize=" + NEW_SIZE,
+                "-Xmx" + HEAP_SIZE, "-Xms" + HEAP_SIZE,
+                (survivorRatio >= 0 ? "-XX:SurvivorRatio=" + survivorRatio : ""),
+                (initRatio >= 0 ? "-XX:InitialSurvivorRatio=" + initRatio : ""),
+                (minRatio >= 0 ? "-XX:MinSurvivorRatio=" + minRatio : ""),
+                (useAdaptiveSizePolicy ? "-XX:+UseAdaptiveSizePolicy" : "-XX:-UseAdaptiveSizePolicy"),
+                SurvivorRatioVerifier.class.getName(),
+                Integer.toString(survivorRatio),
+                Integer.toString(initRatio),
+                Integer.toString(minRatio),
+                Boolean.toString(useAdaptiveSizePolicy)
+        );
+        vmOptions.removeIf((String p) -> p.isEmpty());
+        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+        analyzer.shouldHaveExitValue(0);
+    }
+
+    /**
+     * Class that verifies survivor ratio.
+     * Will be executed in tested VM. Checks initial size of eden and survivor paces with alignment.
+     */
+    public static class SurvivorRatioVerifier {
+
+        public static WhiteBox wb = WhiteBox.getWhiteBox();
+
+        public static final int MAX_ITERATIONS = 10;
+        public static final int ARRAY_LENGTH = 10000;
+        public static final int CHUNK_SIZE = 10000;
+
+        public static byte garbage[][] = new byte[ARRAY_LENGTH][];
+
+        public static void main(String args[]) throws Exception {
+            if (args.length != 4) {
+                throw new IllegalArgumentException("Expected 4 args: <survivorRatio> <initRatio> <minRatio> <useAdaptiveSizePolicy>");
+            }
+            final int survivorRatio = Integer.valueOf(args[0]);
+            final int initRatio = Integer.valueOf(args[1]);
+            final int minRatio = Integer.valueOf(args[2]);
+            final boolean useAdaptiveSizePolicy = Boolean.valueOf(args[3]);
+
+            // we stop testing only here to ensure that JVM will accept
+            // both MinSurvivorRatio and InitialSurvivorRatio regardles to GC
+            if (GCTypes.YoungGCType.getYoungGCType() != GCTypes.YoungGCType.PSNew) {
+                System.out.println("Test is only applicable to Parallel GC");
+                return;
+            }
+
+            // verify initial survivor ratio
+            verifySurvivorRatio(survivorRatio, initRatio, minRatio, useAdaptiveSizePolicy, true);
+
+            // force GC
+            AllocationHelper allocator = new AllocationHelper(MAX_ITERATIONS, ARRAY_LENGTH, CHUNK_SIZE,
+                    () -> (verifySurvivorRatio(survivorRatio, initRatio, minRatio, useAdaptiveSizePolicy, false)));
+            allocator.allocateMemoryAndVerify();
+        }
+
+        /**
+         * Verify actual survivor ratio.
+         *
+         * @param survivorRatio value of SurvivorRatio option, omitted if negative
+         * @param initRatio value of InitialSurvivorRatio option, omitted if negative
+         * @param minRatio value of MinSurvivorRatio option, omitted if negative
+         * @param useAdaptiveSizePolicy value of UseAdaptiveSizePolicy option
+         * @param verifyInitialRatio true if we are going to verify initial ratio
+         */
+        public static Void verifySurvivorRatio(int survivorRatio,
+                int initRatio,
+                int minRatio,
+                boolean useAdaptiveSizePolicy,
+                boolean verifyInitialRatio) {
+
+            MemoryUsage edenUsage = HeapRegionUsageTool.getEdenUsage();
+            MemoryUsage survivorUsage = HeapRegionUsageTool.getSurvivorUsage();
+
+            long alignedNewSize = edenUsage.getMax() + 2 * survivorUsage.getMax();
+            long generationAlignment = wb.psHeapGenerationAlignment();
+
+            if (survivorRatio >= 0) {
+                // -XX:SurvivorRatio was passed to JVM, actual ratio should be SurvivorRatio + 2
+                long expectedSize = HeapRegionUsageTool.alignDown(alignedNewSize / (survivorRatio + 2),
+                        generationAlignment);
+
+                if (survivorUsage.getCommitted() != expectedSize) {
+                    throw new RuntimeException("Expected survivor size is: " + expectedSize
+                            + ", but observed size is: " + survivorUsage.getCommitted());
+                }
+            } else if (verifyInitialRatio || !useAdaptiveSizePolicy) {
+                // In case of initial ratio verification or disabled adaptive size policy
+                // ratio should be equal to InitialSurvivorRatio value
+                long expectedSize = HeapRegionUsageTool.alignDown(alignedNewSize / initRatio,
+                        generationAlignment);
+                if (survivorUsage.getCommitted() != expectedSize) {
+                    throw new RuntimeException("Expected survivor size is: " + expectedSize
+                            + ", but observed size is: " + survivorUsage.getCommitted());
+                }
+            } else {
+                // In any other case actual survivor ratio should not be lower than MinSurvivorRatio
+                // or is should be equal to InitialSurvivorRatio
+                long expectedMinSize = HeapRegionUsageTool.alignDown(alignedNewSize / minRatio,
+                        generationAlignment);
+                long expectedInitSize = HeapRegionUsageTool.alignDown(alignedNewSize / initRatio,
+                        generationAlignment);
+                if (survivorUsage.getCommitted() != expectedInitSize
+                        && survivorUsage.getCommitted() < expectedMinSize) {
+                    throw new RuntimeException("Expected survivor size should be " + expectedMinSize
+                            + " or should be greater then " + expectedMinSize
+                            + ", but observer survivor size is " + survivorUsage.getCommitted());
+                }
+            }
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/arguments/TestNewRatioFlag.java	Tue Sep 01 21:38:07 2015 +0300
@@ -0,0 +1,182 @@
+/*
+* Copyright (c) 2015, 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 TestNewRatioFlag
+ * @key gc
+ * @bug 8025166
+ * @summary Verify that heap devided among generations according to NewRatio
+ * @library /testlibrary /../../test/lib
+ * @modules java.base/sun.misc
+ *          java.management
+ * @build TestNewRatioFlag
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run driver TestNewRatioFlag
+ */
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import jdk.test.lib.HeapRegionUsageTool;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+
+public class TestNewRatioFlag {
+
+    public static final long M = 1024 * 1024;
+    public static final long HEAP_SIZE = 100 * M;
+
+    public static void main(String args[]) throws Exception {
+        LinkedList<String> options = new LinkedList<>(
+                Arrays.asList(Utils.getFilteredTestJavaOpts("(-XX:[^ ]*NewSize=[^ ]+)|(-Xm[ns][^ ]+)"))
+        );
+
+        testNewRatio(4, options);
+        testNewRatio(6, options);
+        testNewRatio(10, options);
+        testNewRatio(15, options);
+        testNewRatio(20, options);
+    }
+
+    /**
+     * Verify that actual size of young gen conforms specified NewRatio
+     *
+     * @param ratio value of NewRatio option
+     * @param options additional options for VM
+     */
+    public static void testNewRatio(int ratio, LinkedList<String> options) throws Exception {
+        LinkedList<String> vmOptions = new LinkedList<>(options);
+        Collections.addAll(vmOptions,
+                "-Xbootclasspath/a:.",
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                "-XX:GCLockerEdenExpansionPercent=0",
+                "-Xmx" + HEAP_SIZE,
+                "-Xms" + HEAP_SIZE,
+                "-XX:NewRatio=" + ratio,
+                "-XX:-UseLargePages",
+                NewRatioVerifier.class.getName(),
+                Integer.toString(ratio)
+        );
+
+        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+        analyzer.shouldHaveExitValue(0);
+        System.out.println(analyzer.getOutput());
+    }
+
+    public static class NewRatioVerifier {
+
+        static WhiteBox wb = WhiteBox.getWhiteBox();
+
+        public static void main(String args[]) {
+            if (args.length != 1) {
+                throw new IllegalArgumentException("Expected 1 arg: <expectedRatio>");
+            }
+            int expectedRatio = Integer.valueOf(args[0]);
+            switch (GCTypes.YoungGCType.getYoungGCType()) {
+                case DefNew:
+                case ParNew:
+                    verifyDefNewNewRatio(expectedRatio);
+                    break;
+                case PSNew:
+                    verifyPSNewRatio(expectedRatio);
+                    break;
+                case G1:
+                    verifyG1NewRatio(expectedRatio);
+                    break;
+                default:
+                    throw new RuntimeException("Unexpected young GC type");
+            }
+        }
+
+        /**
+         * Verify NewSize for DefNew and ParNew collectors.
+         *
+         * Compare expected NewSize calculated according to sizing policies used by DefNew
+         * with NewSize value reported by MemoryPoolMXBeans.
+         */
+        public static void verifyDefNewNewRatio(int expectedRatio) {
+            long initEden = HeapRegionUsageTool.getEdenUsage().getInit();
+            long initSurv = HeapRegionUsageTool.getSurvivorUsage().getInit();
+            long initOld = HeapRegionUsageTool.getOldUsage().getInit();
+
+            long newSize = initEden + 2 * initSurv;
+
+            long expectedNewSize = HeapRegionUsageTool.alignDown(initOld / expectedRatio,
+                    wb.getHeapSpaceAlignment());
+
+            if (expectedNewSize != newSize) {
+                throw new RuntimeException("Expected young gen size is: " + expectedNewSize
+                        + ", but observed new size is: " + newSize);
+            }
+        }
+
+        /**
+         * Verify NewSize for PS collector.
+         * Expected NewSize calculated according to alignment policies used by PS
+         * and then compared with actual NewSize obtained from MemoryPoolMXBeans.
+         */
+        public static void verifyPSNewRatio(int expectedRatio) {
+            long initEden = HeapRegionUsageTool.getEdenUsage().getInit();
+            long initSurv = HeapRegionUsageTool.getSurvivorUsage().getInit();
+            long initOld = HeapRegionUsageTool.getOldUsage().getInit();
+
+            long newSize = initEden + 2 * initSurv;
+
+            long alignedDownNewSize = HeapRegionUsageTool.alignDown(initOld / expectedRatio,
+                    wb.getHeapSpaceAlignment());
+            long expectedNewSize = HeapRegionUsageTool.alignUp(alignedDownNewSize,
+                    wb.psVirtualSpaceAlignment());
+
+            if (expectedNewSize != newSize) {
+                throw new RuntimeException("Expected young gen size is: " + expectedNewSize
+                        + ", but observed new size is: " + newSize);
+            }
+        }
+
+        /**
+         * Verify NewSize for G1 GC.
+         * Amount of young regions calculated according to sizing policies used by G1
+         * and then compared with actual number of young regions derived from
+         * values reported by MemoryPoolMXBeans and region size.
+         */
+        public static void verifyG1NewRatio(int expectedRatio) {
+            long initEden = HeapRegionUsageTool.getEdenUsage().getInit();
+            long initSurv = HeapRegionUsageTool.getSurvivorUsage().getInit();
+            long maxOld = HeapRegionUsageTool.getOldUsage().getMax();
+
+            int regionSize = wb.g1RegionSize();
+            int youngListLength = (int) ((initEden + initSurv) / regionSize);
+            int maxRegions = (int) (maxOld / regionSize);
+            int expectedYoungListLength = (int) (maxRegions / (double) (expectedRatio + 1));
+
+            if (youngListLength != expectedYoungListLength) {
+                throw new RuntimeException("Expected G1 young list length is: " + expectedYoungListLength
+                        + ", but observed young list length is: " + youngListLength);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/arguments/TestNewSizeFlags.java	Tue Sep 01 21:38:07 2015 +0300
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2015, 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 TestNewSizeFlags
+ * @key gc
+ * @bug 8025166
+ * @summary Verify that young gen size conforms values specified by NewSize, MaxNewSize and Xmn options
+ * @library /testlibrary /../../test/lib
+ * @modules java.base/sun.misc
+ *          java.management
+ * @build TestNewSizeFlags
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run driver/timeout=240  TestNewSizeFlags
+ */
+
+import jdk.test.lib.AllocationHelper;
+import java.io.IOException;
+import java.lang.management.MemoryUsage;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import jdk.test.lib.HeapRegionUsageTool;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+
+public class TestNewSizeFlags {
+
+    public static final long M = 1024 * 1024;
+
+    public static void main(String args[]) throws Exception {
+        LinkedList<String> options = new LinkedList<>(
+                Arrays.asList(Utils.getFilteredTestJavaOpts("(-Xm[nsx][^ ]+)|"
+                                + "(-XX:(Max)?((New)|"
+                                + "(Heap))((Size)|"
+                                + "(Ratio))=[^ ]+)"))
+        );
+
+        // Test NewSize and MaxNewSize
+        testNewSizeFlags(20 * M, 10 * M, 30 * M, 40 * M, options, false);
+        testNewSizeFlags(10 * M, 20 * M, 30 * M, 40 * M, options, false);
+        testNewSizeFlags(-1, 20 * M, 30 * M, 40 * M, options, false);
+        testNewSizeFlags(10 * M, -1, 30 * M, 40 * M, options, false);
+        testNewSizeFlags(20 * M, 20 * M, 30 * M, 40 * M, options, false);
+        testNewSizeFlags(20 * M, 30 * M, 40 * M, 50 * M, options, false);
+        testNewSizeFlags(30 * M, 100 * M, 150 * M, 200 * M, options, false);
+        testNewSizeFlags(0, -1, 30 * M, 40 * M, options, false);
+
+        // Test -Xmn
+        testXmnFlags(0, 30 * M, 40 * M, options, true);
+        testXmnFlags(20 * M, 30 * M, 40 * M, options, false);
+        testXmnFlags(50 * M, 70 * M, 100 * M, options, false);
+    }
+
+    /**
+     * Verify that NewSize and MaxNewSize flags affect young gen size.
+     *
+     * @param newSize value of NewSize option, omitted if negative
+     * @param maxNewSize value of MaxNewSize option, omitted if negative
+     * @param heapSize value of HeapSize option
+     * @param maxHeapSize value of MaxHeapSize option
+     * @param options additional options for JVM
+     * @param failureExpected true if JVM should fail with passed heap size options
+     */
+    public static void testNewSizeFlags(long newSize, long maxNewSize,
+            long heapSize, long maxHeapSize,
+            LinkedList<String> options,
+            boolean failureExpected) throws Exception {
+        testVMOptions(newSize, maxNewSize,
+                heapSize, maxHeapSize,
+                newSize, (maxNewSize >= 0 ? Math.max(maxNewSize, newSize) : maxNewSize),
+                options, failureExpected);
+    }
+
+    /**
+     * Verify that -Xmn flag affect young gen size.
+     *
+     * @param mnValue value of -Xmn option
+     * @param heapSize value of HeapSize option
+     * @param maxHeapSize value of MaxHeapSize option
+     * @param options additional options for JVM
+     * @param failureExpected true if JVM should fail with passed heap size options
+     */
+    public static void testXmnFlags(long mnValue,
+            long heapSize, long maxHeapSize,
+            LinkedList<String> options,
+            boolean failureExpected) throws Exception {
+        LinkedList<String> newOptions = new LinkedList<>(options);
+        newOptions.add("-Xmn" + mnValue);
+        testVMOptions(-1, -1,
+                heapSize, maxHeapSize,
+                mnValue, mnValue,
+                newOptions, failureExpected);
+    }
+
+    /**
+     * Verify that NewSize and MaxNewSize flags affect young gen size.
+     *
+     * @param newSize value of NewSize option, omitted if negative
+     * @param maxNewSize value of MaxNewSize option, omitted if negative
+     * @param heapSize value of HeapSize option
+     * @param maxHeapSize value of MaxHeapSize option
+     * @param expectedNewSize expected initial young gen size
+     * @param expectedMaxNewSize expected max young gen size
+     * @param options additional options for JVM
+     * @param failureExpected true if JVM should fail with passed heap size options
+     */
+    public static void testVMOptions(long newSize, long maxNewSize,
+            long heapSize, long maxHeapSize,
+            long expectedNewSize, long expectedMaxNewSize,
+            LinkedList<String> options, boolean failureExpected) throws Exception {
+        OutputAnalyzer analyzer = startVM(options, newSize, maxNewSize, heapSize, maxHeapSize, expectedNewSize, expectedMaxNewSize);
+
+        if (failureExpected) {
+            analyzer.shouldHaveExitValue(1);
+            analyzer.shouldMatch("(Error occurred during initialization of VM)|"
+                    + "(Error: Could not create the Java Virtual Machine.)");
+        } else {
+            analyzer.shouldHaveExitValue(0);
+        }
+    }
+
+    private static OutputAnalyzer startVM(LinkedList<String> options,
+            long newSize, long maxNewSize,
+            long heapSize, long maxHeapSize,
+            long expectedNewSize, long expectedMaxNewSize) throws Exception, IOException {
+        LinkedList<String> vmOptions = new LinkedList<>(options);
+        Collections.addAll(vmOptions,
+                "-Xbootclasspath/a:.",
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                (newSize >= 0 ? "-XX:NewSize=" + newSize : ""),
+                (maxNewSize >= 0 ? "-XX:MaxNewSize=" + maxNewSize : ""),
+                "-Xmx" + maxHeapSize,
+                "-Xms" + heapSize,
+                "-XX:GCLockerEdenExpansionPercent=0",
+                "-XX:-UseLargePages",
+                NewSizeVerifier.class.getName(),
+                Long.toString(expectedNewSize),
+                Long.toString(expectedMaxNewSize)
+        );
+        vmOptions.removeIf(String::isEmpty);
+        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+        return analyzer;
+    }
+
+    /**
+     * NewSizeVerifier checks that initial young gen size is equal to expected
+     * regardful to alignment and that young gen size will not be greater than
+     * expected max size.
+     * In order to verify that young gen size will not be greater then expected
+     * max size, NewSizeVerifier do some object allocation to force garbage
+     * collection and heap expansion.
+     */
+    public static class NewSizeVerifier {
+
+        static WhiteBox wb = WhiteBox.getWhiteBox();
+
+        public static final int ARRAY_LENGTH = 100;
+        public static final int CHUNK_SIZE = 1024;
+        public static final int MAX_ITERATIONS = 10;
+        public static byte garbage[][] = new byte[ARRAY_LENGTH][];
+
+        public static void main(String args[]) throws Exception {
+            if (args.length != 2) {
+                throw new IllegalArgumentException("Expected 2 args: <expectedNewSize> <expectedMaxNewSize>");
+            }
+            final long newSize = Long.valueOf(args[0]);
+            final long maxNewSize = Long.valueOf(args[1]);
+
+            // verify initial size
+            verifyNewSize(newSize, maxNewSize);
+
+            // force GC and verify that size is still correct
+            AllocationHelper allocator = new AllocationHelper(MAX_ITERATIONS, ARRAY_LENGTH, CHUNK_SIZE, () -> (verifyNewSize(newSize, maxNewSize)));
+            allocator.allocateMemoryAndVerifyNoOOME();
+        }
+
+        /**
+         * Verify that actual young gen size conforms NewSize and MaxNewSize values.
+         */
+        public static Void verifyNewSize(long newSize, long maxNewSize) {
+            long alignedNewSize = alignNewSize(newSize);
+            long alignedMaxNewSize = alignNewSize(maxNewSize);
+
+            MemoryUsage youngGenUsage = getYoungGenUsage();
+
+            if (newSize != -1) {
+                if (youngGenUsage.getInit() < alignedNewSize) {
+                    throw new RuntimeException("initial new size < NewSize value: "
+                            + youngGenUsage.getInit() + " < " + alignedNewSize);
+                }
+
+                if (youngGenUsage.getCommitted() < alignedNewSize) {
+                    throw new RuntimeException("actual new size < NewSize value: "
+                            + youngGenUsage.getCommitted() + " < " + alignedNewSize);
+                }
+
+                // for G1 max new size == committed new size
+                if (GCTypes.YoungGCType.getYoungGCType() != GCTypes.YoungGCType.G1
+                        && youngGenUsage.getMax() < alignedNewSize) {
+                    throw new RuntimeException("max new size < NewSize value: "
+                            + youngGenUsage.getMax() + " < " + alignedNewSize);
+                }
+            }
+
+            if (maxNewSize != -1) {
+                if (youngGenUsage.getInit() > alignedMaxNewSize) {
+                    throw new RuntimeException("initial new size > MaxNewSize value: "
+                            + youngGenUsage.getInit() + " > " + alignedMaxNewSize);
+                }
+
+                if (youngGenUsage.getCommitted() > alignedMaxNewSize) {
+                    throw new RuntimeException("actual new size > MaxNewSize value: "
+                            + youngGenUsage.getCommitted() + " > " + alignedMaxNewSize);
+                }
+
+                if (GCTypes.YoungGCType.getYoungGCType() != GCTypes.YoungGCType.G1
+                        && youngGenUsage.getMax() != alignedMaxNewSize) {
+                    throw new RuntimeException("max new size != MaxNewSize value: "
+                            + youngGenUsage.getMax() + " != " + alignedMaxNewSize);
+                }
+            }
+            return null;
+        }
+
+        /**
+         *  Get young gen memory usage.
+         *
+         *  For G1 it is EdenUsage + SurvivorUsage,
+         *  for other GCs it is EdenUsage + 2 * SurvivorUsage.
+         *  For G1 max value is just LONG_MAX.
+         *  For all GCs used value is 0.
+         */
+        private static MemoryUsage getYoungGenUsage() {
+            if (GCTypes.YoungGCType.getYoungGCType() == GCTypes.YoungGCType.G1) {
+                return new MemoryUsage(HeapRegionUsageTool.getEdenUsage().getInit()
+                        + HeapRegionUsageTool.getSurvivorUsage().getInit(),
+                        0,
+                        HeapRegionUsageTool.getEdenUsage().getCommitted()
+                        + HeapRegionUsageTool.getSurvivorUsage().getCommitted(),
+                        Long.MAX_VALUE);
+            } else {
+                return new MemoryUsage(HeapRegionUsageTool.getEdenUsage().getInit()
+                        + HeapRegionUsageTool.getSurvivorUsage().getInit() * 2,
+                        0,
+                        HeapRegionUsageTool.getEdenUsage().getCommitted()
+                        + HeapRegionUsageTool.getSurvivorUsage().getCommitted() * 2,
+                        HeapRegionUsageTool.getEdenUsage().getMax()
+                        + HeapRegionUsageTool.getSurvivorUsage().getMax() * 2);
+            }
+        }
+
+        /**
+         * Align value regardful to used young GC.
+         */
+        public static long alignNewSize(long value) {
+            switch (GCTypes.YoungGCType.getYoungGCType()) {
+                case DefNew:
+                case ParNew:
+                    return HeapRegionUsageTool.alignDown(value, wb.getHeapSpaceAlignment());
+                case PSNew:
+                    return HeapRegionUsageTool.alignUp(HeapRegionUsageTool.alignDown(value,
+                            wb.getHeapSpaceAlignment()),
+                            wb.psVirtualSpaceAlignment());
+                case G1:
+                    return HeapRegionUsageTool.alignUp(value, wb.g1RegionSize());
+                default:
+                    throw new RuntimeException("Unexpected young GC type");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/arguments/TestSurvivorRatioFlag.java	Tue Sep 01 21:38:07 2015 +0300
@@ -0,0 +1,182 @@
+/*
+* Copyright (c) 2015, 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 TestSurvivorRatioFlag
+ * @key gc
+ * @summary Verify that actual survivor ratio is equal to specified SurvivorRatio value
+ * @library /testlibrary /../../test/lib
+ * @modules java.base/sun.misc
+ *          java.management
+ * @build TestSurvivorRatioFlag
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run driver TestSurvivorRatioFlag
+ */
+
+import jdk.test.lib.AllocationHelper;
+import java.lang.management.MemoryUsage;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import jdk.test.lib.HeapRegionUsageTool;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+
+public class TestSurvivorRatioFlag {
+
+    public static final long M = 1024 * 1024;
+    public static final long HEAP_SIZE = 200 * M;
+    public static final long NEW_SIZE = 100 * M;
+
+    public static void main(String args[]) throws Exception {
+        LinkedList<String> options = new LinkedList<>(
+                Arrays.asList(Utils.getFilteredTestJavaOpts("-XX:[^ ]*SurvivorRatio=[^ ]+"))
+        );
+
+        testSurvivorRatio(3, options);
+        testSurvivorRatio(6, options);
+        testSurvivorRatio(10, options);
+        testSurvivorRatio(15, options);
+        testSurvivorRatio(20, options);
+    }
+
+    /**
+     * Verify that actual survivor ratio equal to specified.
+     *
+     * @param ratio survivor ratio that be verified
+     * @param options additional options to JVM
+     */
+    public static void testSurvivorRatio(int ratio, LinkedList<String> options) throws Exception {
+
+        LinkedList<String> vmOptions = new LinkedList<>(options);
+
+        Collections.addAll(vmOptions,
+                "-Xbootclasspath/a:.",
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                "-XX:GCLockerEdenExpansionPercent=0",
+                "-XX:MaxNewSize=" + NEW_SIZE,
+                "-XX:NewSize=" + NEW_SIZE,
+                "-Xmx" + HEAP_SIZE,
+                "-Xms" + HEAP_SIZE,
+                "-XX:SurvivorRatio=" + ratio,
+                SurvivorRatioVerifier.class.getName(),
+                Integer.toString(ratio)
+        );
+
+        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+        analyzer.shouldHaveExitValue(0);
+    }
+
+    /**
+     * Class that verifies survivor ratio.
+     */
+    public static class SurvivorRatioVerifier {
+
+        static WhiteBox wb = WhiteBox.getWhiteBox();
+
+        public static final int MAX_ITERATIONS = 10;
+        public static final int ARRAY_LENGTH = 10000;
+        public static final int CHUNK_SIZE = 10000;
+
+        public static void main(String args[]) throws Exception {
+            if (args.length != 1) {
+                throw new IllegalArgumentException("Expected 1 arg: <ratio>");
+            }
+            final int ratio = Integer.valueOf(args[0]);
+
+            AllocationHelper allocator = new AllocationHelper(MAX_ITERATIONS, ARRAY_LENGTH, CHUNK_SIZE, () -> (verifySurvivorRatio(ratio)));
+            allocator.allocateMemoryAndVerify();
+        }
+
+        /**
+         * Verify that actual survivor ratio is equal to expected.
+         * Depending on selected young GC we verify that:
+         * - for DefNew and ParNew: eden_size / survivor_size is close to expectedRatio;
+         * - for PSNew:             survivor_size equal to young_gen_size / expectedRatio;
+         * - for G1:                survivor_regions <= young_list_length / expectedRatio.
+         */
+        public static Void verifySurvivorRatio(int expectedRatio) {
+            GCTypes.YoungGCType type = GCTypes.YoungGCType.getYoungGCType();
+            switch (type) {
+                case DefNew:
+                case ParNew:
+                    verifyDefNewSurvivorRatio(expectedRatio);
+                    break;
+                case PSNew:
+                    verifyPSSurvivorRatio(expectedRatio);
+                    break;
+                case G1:
+                    verifyG1SurvivorRatio(expectedRatio);
+                    break;
+                default:
+                    throw new RuntimeException("Unexpected young GC type");
+            }
+            return null;
+        }
+
+        private static void verifyDefNewSurvivorRatio(int expectedRatio) {
+            MemoryUsage edenUsage = HeapRegionUsageTool.getEdenUsage();
+            MemoryUsage survivorUsage = HeapRegionUsageTool.getSurvivorUsage();
+
+            int actualRatio = (int) (edenUsage.getCommitted() / survivorUsage.getCommitted());
+            if (Math.abs(actualRatio - expectedRatio) > 1) {
+                throw new RuntimeException("Expected survivor ratio is: " + expectedRatio
+                        + ", but observed ratio is: " + actualRatio);
+            }
+        }
+
+        private static void verifyPSSurvivorRatio(int expectedRatio) {
+            MemoryUsage edenUsage = HeapRegionUsageTool.getEdenUsage();
+            MemoryUsage survivorUsage = HeapRegionUsageTool.getSurvivorUsage();
+
+            long youngGenSize = edenUsage.getMax() + 2 * survivorUsage.getMax();
+            // for Paralle GC Min/InitialSurvivorRatio = SurvivorRatio + 2
+            long expectedSize = HeapRegionUsageTool.alignDown(youngGenSize / (expectedRatio + 2),
+                    wb.psHeapGenerationAlignment());
+
+            if (expectedSize != survivorUsage.getCommitted()) {
+                throw new RuntimeException("Expected survivor size is: " + expectedSize
+                        + ", but observed size is: " + survivorUsage.getCommitted());
+            }
+        }
+
+        private static void verifyG1SurvivorRatio(int expectedRatio) {
+            MemoryUsage survivorUsage = HeapRegionUsageTool.getSurvivorUsage();
+
+            int regionSize = wb.g1RegionSize();
+            int youngListLength = (int) Math.max(NEW_SIZE / regionSize, 1);
+            int expectedSurvivorRegions = (int) Math.ceil(youngListLength / (double) expectedRatio);
+            int observedSurvivorRegions = (int) (survivorUsage.getCommitted() / regionSize);
+
+            if (expectedSurvivorRegions < observedSurvivorRegions) {
+                throw new RuntimeException("Expected amount of G1 survivor regions is "
+                        + expectedSurvivorRegions + ", but observed "
+                        + observedSurvivorRegions);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/arguments/TestTargetSurvivorRatioFlag.java	Tue Sep 01 21:38:07 2015 +0300
@@ -0,0 +1,319 @@
+/*
+* Copyright (c) 2015, 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 TestTargetSurvivorRatioFlag
+ * @key gc
+ * @summary Verify that option TargetSurvivorRatio affects survivor space occupancy after minor GC.
+ * @library /testlibrary /../../test/lib
+ * @modules java.base/sun.misc
+ *          java.management
+ * @build TestTargetSurvivorRatioFlag
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run driver TestTargetSurvivorRatioFlag
+ */
+
+import jdk.test.lib.AllocationHelper;
+import java.lang.management.GarbageCollectorMXBean;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import jdk.test.lib.HeapRegionUsageTool;
+import sun.misc.Unsafe;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+
+/* In order to test that TargetSurvivorRatio affects survivor space occupancy
+ * we setup fixed MaxTenuringThreshold and then verifying that if size of allocated
+ * objects is lower than (survivor_size * TargetSurvivorRatio / 100) then objects
+ * will stay in survivor space until MaxTenuringThreshold minor GC cycles.
+ * If more than (survivor_size * TargetSurvivorRatio / 100) objects were allocated,
+ * then we verify that after MaxTenuringThreshold minor GC cycles survivor space
+ * is almost empty.
+ */
+public class TestTargetSurvivorRatioFlag {
+
+    public static final long M = 1024 * 1024;
+
+    // VM option values
+    public static final long MAX_NEW_SIZE = 40 * M;
+    public static final int SURVIVOR_RATIO = 8;
+    public static final int MAX_TENURING_THRESHOLD = 15;
+
+    // Value used to estimate amount of memory that should be allocated
+    // and placed in survivor space.
+    public static final double DELTA = 0.25;
+
+    // Max variance of observed ratio
+    public static double VARIANCE = 1;
+
+    // Messages used by debuggee
+    public static final String UNSUPPORTED_GC = "Unsupported GC";
+    public static final String START_TEST = "Start test";
+    public static final String END_TEST = "End test";
+
+    // Patterns used during log parsing
+    public static final String TENURING_DISTRIBUTION = "Desired survivor size";
+    public static final String AGE_TABLE_ENTRY = "-[\\s]+age[\\s]+([0-9]+):[\\s]+([0-9]+)[\\s]+bytes,[\\s]+([0-9]+)[\\s]+total";
+    public static final String MAX_SURVIVOR_SIZE = "Max survivor size: ([0-9]+)";
+
+    public static void main(String args[]) throws Exception {
+
+        LinkedList<String> options = new LinkedList<>(Arrays.asList(Utils.getTestJavaOpts()));
+
+        // Need to consider the effect of TargetPLABWastePct=1 for G1 GC
+        if (options.contains("-XX:+UseG1GC")) {
+            VARIANCE = 2;
+        } else {
+            VARIANCE = 1;
+        }
+
+        negativeTest(-1, options);
+        negativeTest(101, options);
+
+        positiveTest(20, options);
+        positiveTest(30, options);
+        positiveTest(55, options);
+        positiveTest(70, options);
+    }
+
+    /**
+     * Verify that VM will fail to start with specified TargetSurvivorRatio
+     *
+     * @param ratio value of TargetSurvivorRatio
+     * @param options additional VM options
+     */
+    public static void negativeTest(int ratio, LinkedList<String> options) throws Exception {
+        LinkedList<String> vmOptions = new LinkedList<>(options);
+        vmOptions.add("-XX:TargetSurvivorRatio=" + ratio);
+        vmOptions.add("-version");
+
+        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+
+        analyzer.shouldHaveExitValue(1);
+        analyzer.shouldContain("Error: Could not create the Java Virtual Machine.");
+    }
+
+    /**
+     * Verify that actual survivor space usage ratio conforms specified TargetSurvivorRatio
+     *
+     * @param ratio value of TargetSurvivorRatio
+     * @param options additional VM options
+     */
+    public static void positiveTest(int ratio, LinkedList<String> options) throws Exception {
+        LinkedList<String> vmOptions = new LinkedList<>(options);
+        Collections.addAll(vmOptions,
+                "-Xbootclasspath/a:.",
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                "-XX:+UseAdaptiveSizePolicy",
+                "-XX:+PrintTenuringDistribution",
+                "-XX:MaxTenuringThreshold=" + MAX_TENURING_THRESHOLD,
+                "-XX:NewSize=" + MAX_NEW_SIZE,
+                "-XX:MaxNewSize=" + MAX_NEW_SIZE,
+                "-XX:InitialHeapSize=" + 2 * MAX_NEW_SIZE,
+                "-XX:MaxHeapSize=" + 2 * MAX_NEW_SIZE,
+                "-XX:SurvivorRatio=" + SURVIVOR_RATIO,
+                "-XX:TargetSurvivorRatio=" + ratio,
+                // For reducing variance of survivor size.
+                "-XX:TargetPLABWastePct=" + 1,
+                TargetSurvivorRatioVerifier.class.getName(),
+                Integer.toString(ratio)
+        );
+
+        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
+        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
+
+        analyzer.shouldHaveExitValue(0);
+
+        String output = analyzer.getOutput();
+
+        // Test avoids verification for parallel GC
+        if (!output.contains(UNSUPPORTED_GC)) {
+            // Two tests should be done - when actual ratio is lower than TargetSurvivorRatio
+            // and when it is higher. We chech that output contains results for exactly two tests.
+            List<Double> ratios = parseTestOutput(output);
+
+            if (ratios.size() != 2) {
+                System.out.println(output);
+                throw new RuntimeException("Expected number of ratios extraced for output is 2,"
+                        + " but " + ratios.size() + " ratios were extracted");
+            }
+
+            // At the end of the first test survivor space usage ratio should lies between
+            // TargetSurvivorRatio and TargetSurvivorRatio - 2*DELTA
+            if (ratio < ratios.get(0) || ratio - ratios.get(0) > VARIANCE) {
+                System.out.println(output);
+                throw new RuntimeException("Survivor space usage ratio expected to be close to "
+                        + ratio + ", but observed ratio is: " + ratios.get(0));
+            }
+
+            // After second test survivor space should be almost empty.
+            if (ratios.get(1) > VARIANCE) {
+                System.out.println(output);
+                throw new RuntimeException("Survivor space expected to be empty due to "
+                        + "TargetSurvivorRatio overlimit, however observed "
+                        + "survivor space usage ratio is: " + ratios.get(1));
+            }
+        } else {
+            System.out.println("Selected GC does not support TargetSurvivorRatio option.");
+        }
+    }
+
+    /**
+     * Parse output produced by TargetSurvivorRatioVerifier.
+     *
+     * @param output output obtained from TargetSurvivorRatioVerifier
+     * @return list of parsed test results, where each result is an actual
+     *         survivor ratio after MaxTenuringThreshold minor GC cycles.
+     */
+    public static List<Double> parseTestOutput(String output) {
+        List<Double> ratios = new LinkedList<Double>();
+        String lines[] = output.split("[\n\r]");
+        boolean testStarted = false;
+        long survivorSize = 0;
+        long survivorOccupancy = 0;
+        int gcCount = 0;
+        Pattern ageTableEntry = Pattern.compile(AGE_TABLE_ENTRY);
+        Pattern maxSurvivorSize = Pattern.compile(MAX_SURVIVOR_SIZE);
+        for (String line : lines) {
+            if (Pattern.matches(MAX_SURVIVOR_SIZE, line)) {
+                // We found estimated survivor space size
+                Matcher m = maxSurvivorSize.matcher(line);
+                m.find();
+                survivorSize = Long.valueOf(m.group(1));
+            } else if (line.contains(START_TEST) && !testStarted) {
+                // Start collecting test results
+                testStarted = true;
+                gcCount = 0;
+            } else if (testStarted) {
+                if (line.contains(TENURING_DISTRIBUTION)) {
+                    // We found start of output emitted by -XX:+PrintTenuringDistribution
+                    // If it is associated with "MaxTenuringThreshold" GC cycle, then it's
+                    // time to report observed survivor usage ratio
+                    gcCount++;
+                    double survivorRatio = survivorOccupancy / (double) survivorSize;
+                    if (gcCount == MAX_TENURING_THRESHOLD || gcCount == MAX_TENURING_THRESHOLD * 2) {
+                        ratios.add(survivorRatio * 100.0);
+                        testStarted = false;
+                    }
+                    survivorOccupancy = 0;
+                } else if (Pattern.matches(AGE_TABLE_ENTRY, line)) {
+                    // Obtain survivor space usage from "total" age table log entry
+                    Matcher m = ageTableEntry.matcher(line);
+                    m.find();
+                    survivorOccupancy = Long.valueOf(m.group(3));
+                } else if (line.contains(END_TEST)) {
+                    // It is expected to find at least MaxTenuringThreshold GC events
+                    // until test end
+                    if (gcCount < MAX_TENURING_THRESHOLD) {
+                        throw new RuntimeException("Observed " + gcCount + " GC events, "
+                                + "while it is expected to see at least "
+                                + MAX_TENURING_THRESHOLD);
+                    }
+                    testStarted = false;
+                }
+            }
+        }
+        return ratios;
+    }
+
+    public static class TargetSurvivorRatioVerifier {
+
+        static final WhiteBox wb = WhiteBox.getWhiteBox();
+        static final Unsafe unsafe = Utils.getUnsafe();
+
+        // Desired size of memory allocated at once
+        public static final int CHUNK_SIZE = 1024;
+        // Length of byte[] array that will have occupy CHUNK_SIZE bytes in heap
+        public static final int ARRAY_LENGTH = CHUNK_SIZE - Unsafe.ARRAY_BYTE_BASE_OFFSET;
+
+        public static void main(String args[]) throws Exception {
+            if (args.length != 1) {
+                throw new IllegalArgumentException("Expected 1 arg: <ratio>");
+            }
+            if (GCTypes.YoungGCType.getYoungGCType() == GCTypes.YoungGCType.PSNew) {
+                System.out.println(UNSUPPORTED_GC);
+                return;
+            }
+
+            int ratio = Integer.valueOf(args[0]);
+            long maxSurvivorSize = getMaxSurvivorSize();
+            System.out.println("Max survivor size: " + maxSurvivorSize);
+
+            allocateMemory(ratio - DELTA, maxSurvivorSize);
+            allocateMemory(ratio + DELTA, maxSurvivorSize);
+        }
+
+        /**
+         * Allocate (<b>ratio</b> * <b>maxSize</b> / 100) bytes of objects
+         * and force at least "MaxTenuringThreshold" minor GCs.
+         *
+         * @param ratio ratio used to calculate how many objects should be allocated
+         * @param maxSize estimated max survivor space size
+         */
+        public static void allocateMemory(double ratio, long maxSize) throws Exception {
+            GarbageCollectorMXBean youngGCBean = GCTypes.YoungGCType.getYoungGCBean();
+            long garbageSize = (long) (maxSize * (ratio / 100.0));
+            int arrayLength = (int) (garbageSize / CHUNK_SIZE);
+            AllocationHelper allocator = new AllocationHelper(1, arrayLength, ARRAY_LENGTH, null);
+
+            System.out.println(START_TEST);
+            System.gc();
+            final long initialGcId = youngGCBean.getCollectionCount();
+            // allocate memory
+            allocator.allocateMemoryAndVerify();
+
+            // force minor GC
+            while (youngGCBean.getCollectionCount() <= initialGcId + MAX_TENURING_THRESHOLD * 2) {
+                byte b[] = new byte[ARRAY_LENGTH];
+            }
+
+            allocator.release();
+            System.out.println(END_TEST);
+        }
+
+        /**
+         * Estimate max survivor space size.
+         *
+         * For non-G1 GC returns value reported by MemoryPoolMXBean
+         * associated with survivor space.
+         * For G1 GC return max number of survivor regions * region size.
+         * Number if survivor regions estimated from MaxNewSize and SurvivorRatio.
+         */
+        public static long getMaxSurvivorSize() {
+            if (GCTypes.YoungGCType.getYoungGCType() == GCTypes.YoungGCType.G1) {
+                int youngLength = (int) Math.max(MAX_NEW_SIZE / wb.g1RegionSize(), 1);
+                return (long) Math.ceil(youngLength / (double) SURVIVOR_RATIO) * wb.g1RegionSize();
+            } else {
+                return HeapRegionUsageTool.getSurvivorUsage().getMax();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/jdk/test/lib/AllocationHelper.java	Tue Sep 01 21:38:07 2015 +0300
@@ -0,0 +1,116 @@
+/*
+* Copyright (c) 2015, 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.
+*/
+
+package jdk.test.lib;
+
+import java.util.LinkedList;
+import java.util.concurrent.Callable;
+
+/**
+ * Helper class which allocates memory.
+ *
+ * Typical usage:
+ * <pre>
+ * {@code
+ *           AllocationHelper allocator = new AllocationHelper(MAX_ITERATIONS, ARRAY_LENGTH, CHUNK_SIZE,
+ *                   () -> (verifier()));
+ *           // Allocate byte[CHUNK_SIZE] ARRAY_LENGTH times. Total allocated bytes will be CHUNK_SIZE * ARRAY_LENGTH + refs length.
+ *           // Then invoke verifier and iterate MAX_ITERATIONS times.
+ *           allocator.allocateMemoryAndVerify();
+ * }
+ * </pre>
+ */
+public final class AllocationHelper {
+
+    private final int arrayLength;
+    private final int maxIterations;
+    private final int chunkSize;
+
+    // garbageStorage is used to store link to garbage to prevent optimization.
+    private static Object garbageStorage;
+    private byte garbage[][];
+    private final Callable<?> verifierInstance;
+
+    /**
+     * Create an AllocationHelper with specified iteration count, array length, chunk size and verifier.
+     *
+     * @param maxIterations
+     * @param arrayLength
+     * @param chunkSize
+     * @param verifier - Callable instance which will be invoked after all allocation cycle. Can be null;
+     */
+    public AllocationHelper(int maxIterations, int arrayLength, int chunkSize, Callable<?> verifier) {
+        if ((arrayLength <= 0) || (maxIterations <= 0) || (chunkSize <= 0)) {
+            throw new IllegalArgumentException("maxIterations, arrayLength and chunkSize should be greater then 0.");
+        }
+        this.arrayLength = arrayLength;
+        this.maxIterations = maxIterations;
+        this.chunkSize = chunkSize;
+        verifierInstance = verifier;
+        garbage = new byte[this.arrayLength][];
+        garbageStorage = garbage;
+    }
+
+    private void allocateMemoryOneIteration() {
+        for (int j = 0; j < arrayLength; j++) {
+            garbage[j] = new byte[chunkSize];
+        }
+    }
+
+    /**
+     * Allocate memory and invoke Verifier during all iteration.
+     *
+     * @throws java.lang.Exception
+     */
+    public void allocateMemoryAndVerify() throws Exception {
+        for (int i = 0; i < maxIterations; i++) {
+            allocateMemoryOneIteration();
+            if (verifierInstance != null) {
+                verifierInstance.call();
+            }
+        }
+    }
+
+    /**
+     * The same as allocateMemoryAndVerify() but hides OOME
+     *
+     * @throws Exception
+     */
+    public void allocateMemoryAndVerifyNoOOME() throws Exception {
+        try {
+            allocateMemoryAndVerify();
+        } catch (OutOfMemoryError e) {
+            // exit on OOME
+        }
+    }
+
+    /**
+     * Release link to allocated garbage to make it available for further GC
+     */
+    public void release() {
+        if (garbage != null) {
+            garbage = null;
+            garbageStorage = null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/jdk/test/lib/HeapRegionUsageTool.java	Tue Sep 01 21:38:07 2015 +0300
@@ -0,0 +1,107 @@
+/*
+* Copyright (c) 2015, 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.
+*/
+
+package jdk.test.lib;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryUsage;
+
+/**
+ * Utility class used by tests to get heap region usage.
+ */
+public final class HeapRegionUsageTool {
+
+    /**
+     * Get MemoryUsage from MemoryPoolMXBean which name matches passed string.
+     *
+     * @param name
+     * @return MemoryUsage
+     */
+    private static MemoryUsage getUsage(String name){
+        for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
+            if (pool.getName().matches(name)) {
+                return pool.getUsage();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get MemoryUsage of Eden space.
+     *
+     * @return MemoryUsage
+     */
+    public static MemoryUsage getEdenUsage() {
+        return getUsage(".*Eden.*");
+    }
+
+    /**
+     * Get MemoryUsage of Survivor space.
+     *
+     * @return MemoryUsage
+     */
+    public static MemoryUsage getSurvivorUsage() {
+        return getUsage(".*Survivor.*");
+    }
+
+    /**
+     * Get memory usage of Tenured space
+     *
+     * @return MemoryUsage
+     */
+    public static MemoryUsage getOldUsage() {
+        return getUsage(".*(Old|Tenured).*");
+    }
+
+    /**
+     * Get heap usage.
+     *
+     * @return MemoryUsage
+     */
+    public static MemoryUsage getHeapUsage() {
+        return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
+    }
+
+    /**
+     * Helper function to align up.
+     *
+     * @param value
+     * @param alignment
+     * @return aligned value
+     */
+    public static long alignUp(long value, long alignment) {
+        return (value + alignment - 1) & ~(alignment - 1);
+    }
+
+    /**
+     * Helper function to align down.
+     *
+     * @param value
+     * @param alignment
+     * @return aligned value
+     */
+    public static long alignDown(long value, long alignment) {
+        return value & ~(alignment - 1);
+    }
+}