< prev index next >

test/gc/g1/plab/TestPLABPromotion.java

Print this page




  24  /*
  25  * @test TestPLABPromotion
  26  * @bug 8141278 8141141
  27  * @summary Test PLAB promotion
  28  * @requires vm.gc=="G1" | vm.gc=="null"
  29  * @requires vm.opt.FlightRecorder != true
  30  * @library /testlibrary /test/lib /
  31  * @modules java.management
  32  * @build ClassFileInstaller
  33  *        sun.hotspot.WhiteBox
  34  *        gc.g1.plab.lib.MemoryConsumer
  35  *        gc.g1.plab.lib.LogParser
  36  *        gc.g1.plab.lib.AppPLABPromotion
  37  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  38  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  39  * @run main/timeout=240 gc.g1.plab.TestPLABPromotion
  40  */
  41 package gc.g1.plab;
  42 
  43 import java.util.List;
  44 import java.util.Map;
  45 import java.util.Arrays;
  46 import java.io.PrintStream;
  47 
  48 import gc.g1.plab.lib.AppPLABPromotion;
  49 import gc.g1.plab.lib.LogParser;
  50 import gc.g1.plab.lib.PLABUtils;

  51 
  52 import jdk.test.lib.OutputAnalyzer;
  53 import jdk.test.lib.ProcessTools;
  54 import jdk.test.lib.Platform;
  55 
  56 /**
  57  * Test checks PLAB promotion of different size objects.
  58  */
  59 public class TestPLABPromotion {
  60 
  61     // GC ID with survivor PLAB statistics
  62     private final static long GC_ID_SURVIVOR_STATS = 1l;
  63     // GC ID with old PLAB statistics
  64     private final static long GC_ID_OLD_STATS = 2l;
  65 






  66     // Allowable difference for memory consumption (percentage)
  67     private final static long MEM_DIFFERENCE_PCT = 5;
  68 
  69     private static final int PLAB_SIZE_SMALL = 1024;
  70     private static final int PLAB_SIZE_MEDIUM = 4096;
  71     private static final int PLAB_SIZE_HIGH = 65536;
  72     private static final int OBJECT_SIZE_SMALL = 10;
  73     private static final int OBJECT_SIZE_MEDIUM = 100;
  74     private static final int OBJECT_SIZE_HIGH = 1000;
  75     private static final int GC_NUM_SMALL = 1;
  76     private static final int GC_NUM_MEDIUM = 3;
  77     private static final int GC_NUM_HIGH = 7;
  78     private static final int WASTE_PCT_SMALL = 10;
  79     private static final int WASTE_PCT_MEDIUM = 20;
  80     private static final int WASTE_PCT_HIGH = 30;
  81     private static final int YOUNG_SIZE_LOW = 16;
  82     private static final int YOUNG_SIZE_HIGH = 64;
  83     private static final boolean PLAB_FIXED = true;
  84     private static final boolean PLAB_DYNAMIC = false;
  85 


 103         new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_HIGH, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, PLAB_DYNAMIC, true, true),
 104         new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_MEDIUM, OBJECT_SIZE_SMALL, GC_NUM_SMALL, YOUNG_SIZE_LOW, PLAB_DYNAMIC, true, true),
 105         new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_MEDIUM, OBJECT_SIZE_HIGH, GC_NUM_HIGH, YOUNG_SIZE_HIGH, PLAB_DYNAMIC, true, false),
 106         new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_SMALL, OBJECT_SIZE_MEDIUM, GC_NUM_MEDIUM, YOUNG_SIZE_LOW, PLAB_DYNAMIC, true, true),
 107         new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_HIGH, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_HIGH, PLAB_DYNAMIC, true, true),
 108         new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_HIGH, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_LOW, PLAB_DYNAMIC, true, true)
 109     };
 110 
 111     public static void main(String[] args) throws Throwable {
 112 
 113         for (TestCase testCase : TEST_CASES) {
 114             // What we going to check.
 115             testCase.print(System.out);
 116             List<String> options = PLABUtils.prepareOptions(testCase.toOptions());
 117             options.add(AppPLABPromotion.class.getName());
 118             OutputAnalyzer out = ProcessTools.executeTestJvm(options.toArray(new String[options.size()]));
 119             if (out.getExitValue() != 0) {
 120                 System.out.println(out.getOutput());
 121                 throw new RuntimeException("Expect exit code 0.");
 122             }
 123             checkResults(out.getOutput(), testCase);

 124         }
 125     }
 126 
 127     private static void checkResults(String output, TestCase testCase) {
 128         long plabAllocatedSurvivor;
 129         long directAllocatedSurvivor;
 130         long plabAllocatedOld;
 131         long directAllocatedOld;
 132         long memAllocated = testCase.getMemToFill();
 133         LogParser logParser = new LogParser(output);
 134 
 135         Map<String, Long> survivorStats = getPlabStats(logParser, LogParser.ReportType.SURVIVOR_STATS, GC_ID_SURVIVOR_STATS);
 136         Map<String, Long> oldStats = getPlabStats(logParser, LogParser.ReportType.OLD_STATS, GC_ID_OLD_STATS);



 137 
 138         plabAllocatedSurvivor = survivorStats.get("used");
 139         directAllocatedSurvivor = survivorStats.get("direct allocated");
 140         plabAllocatedOld = oldStats.get("used");
 141         directAllocatedOld = oldStats.get("direct allocated");
 142 
 143         System.out.printf("Survivor PLAB allocated:%17d Direct allocated: %17d Mem consumed:%17d%n", plabAllocatedSurvivor, directAllocatedSurvivor, memAllocated);
 144         System.out.printf("Old      PLAB allocated:%17d Direct allocated: %17d Mem consumed:%17d%n", plabAllocatedOld, directAllocatedOld, memAllocated);
 145 
 146         // Unreachable objects case
 147         if (testCase.isDeadObjectCase()) {
 148             // No dead objects should be promoted
 149             if (!(checkRatio(plabAllocatedSurvivor, memAllocated) && checkRatio(directAllocatedSurvivor, memAllocated))) {
 150                 System.out.println(output);
 151                 throw new RuntimeException("Unreachable objects should not be allocated using PLAB or direct allocated to Survivor");
 152             }
 153             if (!(checkRatio(plabAllocatedOld, memAllocated) && checkRatio(directAllocatedOld, memAllocated))) {
 154                 System.out.println(output);
 155                 throw new RuntimeException("Unreachable objects should not be allocated using PLAB or direct allocated to Old");
 156             }
 157         } else {
 158             // Live objects case
 159             if (testCase.isPromotedByPLAB()) {
 160                 // All live small objects should be promoted using PLAB
 161                 if (!checkDifferenceRatio(plabAllocatedSurvivor, memAllocated)) {
 162                     System.out.println(output);
 163                     throw new RuntimeException("Expect that Survivor PLAB allocation are similar to all mem consumed");
 164                 }
 165                 if (!checkDifferenceRatio(plabAllocatedOld, memAllocated)) {
 166                     System.out.println(output);
 167                     throw new RuntimeException("Expect that Old PLAB allocation are similar to all mem consumed");
 168                 }
 169             } else {
 170                 // All big objects should be directly allocated
 171                 if (!checkDifferenceRatio(directAllocatedSurvivor, memAllocated)) {
 172                     System.out.println(output);
 173                     throw new RuntimeException("Test fails. Expect that Survivor direct allocation are similar to all mem consumed");
 174                 }
 175                 if (!checkDifferenceRatio(directAllocatedOld, memAllocated)) {
 176                     System.out.println(output);
 177                     throw new RuntimeException("Test fails. Expect that Old direct allocation are similar to all mem consumed");
 178                 }

 179             }
 180 

 181             // All promoted objects size should be similar to all consumed memory
 182             if (!checkDifferenceRatio(plabAllocatedSurvivor + directAllocatedSurvivor, memAllocated)) {
 183                 System.out.println(output);
 184                 throw new RuntimeException("Test fails. Expect that Survivor gen total allocation are similar to all mem consumed");
 185             }
 186             if (!checkDifferenceRatio(plabAllocatedOld + directAllocatedOld, memAllocated)) {










 187                 System.out.println(output);
 188                 throw new RuntimeException("Test fails. Expect that Old gen total allocation are similar to all mem consumed");
 189             }
 190         }
 191         System.out.println("Test passed!");























 192     }
 193 
 194     /**
 195      * Returns true if checkedValue is less than MEM_DIFFERENCE_PCT percent of controlValue.
 196      *
 197      * @param checkedValue - checked value
 198      * @param controlValue - referent value
 199      * @return true if checkedValue is less than MEM_DIFFERENCE_PCT percent of controlValue
 200      */
 201     private static boolean checkRatio(long checkedValue, long controlValue) {
 202         return (Math.abs(checkedValue) / controlValue) * 100L < MEM_DIFFERENCE_PCT;
 203     }
 204 
 205     /**
 206      * Returns true if difference of checkedValue and controlValue is less than
 207      * MEM_DIFFERENCE_PCT percent of controlValue.
 208      *
 209      * @param checkedValue - checked value
 210      * @param controlValue - referent value
 211      * @return true if difference of checkedValue and controlValue is less than
 212      * MEM_DIFFERENCE_PCT percent of controlValue
 213      */
 214     private static boolean checkDifferenceRatio(long checkedValue, long controlValue) {
 215         return (Math.abs(checkedValue - controlValue) / controlValue) * 100L < MEM_DIFFERENCE_PCT;
 216     }
 217 
 218     private static Map<String, Long> getPlabStats(LogParser logParser, LogParser.ReportType type, long gc_id) {
 219 
 220         Map<String, Long> survivorStats = logParser.getEntries()
 221                 .get(gc_id)
 222                 .get(type);
 223         return survivorStats;
 224     }
 225 
 226     /**
 227      * Description of one test case.
 228      */
 229     private static class TestCase {
 230 
 231         private final int wastePct;
 232         private final int plabSize;
 233         private final int chunkSize;
 234         private final int parGCThreads;
 235         private final int edenSize;
 236         private final boolean plabIsFixed;
 237         private final boolean objectsAreReachable;
 238         private final boolean promotedByPLAB;
 239 
 240         /**
 241          * @param wastePct
 242          * ParallelGCBufferWastePct
 243          * @param plabSize




  24  /*
  25  * @test TestPLABPromotion
  26  * @bug 8141278 8141141
  27  * @summary Test PLAB promotion
  28  * @requires vm.gc=="G1" | vm.gc=="null"
  29  * @requires vm.opt.FlightRecorder != true
  30  * @library /testlibrary /test/lib /
  31  * @modules java.management
  32  * @build ClassFileInstaller
  33  *        sun.hotspot.WhiteBox
  34  *        gc.g1.plab.lib.MemoryConsumer
  35  *        gc.g1.plab.lib.LogParser
  36  *        gc.g1.plab.lib.AppPLABPromotion
  37  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  38  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  39  * @run main/timeout=240 gc.g1.plab.TestPLABPromotion
  40  */
  41 package gc.g1.plab;
  42 
  43 import java.util.List;

  44 import java.util.Arrays;
  45 import java.io.PrintStream;
  46 
  47 import gc.g1.plab.lib.AppPLABPromotion;
  48 import gc.g1.plab.lib.LogParser;
  49 import gc.g1.plab.lib.PLABUtils;
  50 import gc.g1.plab.lib.PlabInfo;
  51 
  52 import jdk.test.lib.OutputAnalyzer;
  53 import jdk.test.lib.ProcessTools;

  54 
  55 /**
  56  * Test checks PLAB promotion of different size objects.
  57  */
  58 public class TestPLABPromotion {
  59 
  60     // GC ID with survivor PLAB statistics
  61     private final static long GC_ID_SURVIVOR_STATS = 1l;
  62     // GC ID with old PLAB statistics
  63     private final static long GC_ID_OLD_STATS = 2l;
  64 
  65     private final static String PLAB_USED_FIELD_NAME = "used";
  66     private final static String PLAB_DIRECT_ALLOCATED_FIELD_NAME = "direct allocated";
  67     private final static List<String> FIELDS_TO_EXTRACT = Arrays.asList(PLAB_USED_FIELD_NAME, PLAB_DIRECT_ALLOCATED_FIELD_NAME);
  68 
  69     private static String output;
  70 
  71     // Allowable difference for memory consumption (percentage)
  72     private final static long MEM_DIFFERENCE_PCT = 5;
  73 
  74     private static final int PLAB_SIZE_SMALL = 1024;
  75     private static final int PLAB_SIZE_MEDIUM = 4096;
  76     private static final int PLAB_SIZE_HIGH = 65536;
  77     private static final int OBJECT_SIZE_SMALL = 10;
  78     private static final int OBJECT_SIZE_MEDIUM = 100;
  79     private static final int OBJECT_SIZE_HIGH = 1000;
  80     private static final int GC_NUM_SMALL = 1;
  81     private static final int GC_NUM_MEDIUM = 3;
  82     private static final int GC_NUM_HIGH = 7;
  83     private static final int WASTE_PCT_SMALL = 10;
  84     private static final int WASTE_PCT_MEDIUM = 20;
  85     private static final int WASTE_PCT_HIGH = 30;
  86     private static final int YOUNG_SIZE_LOW = 16;
  87     private static final int YOUNG_SIZE_HIGH = 64;
  88     private static final boolean PLAB_FIXED = true;
  89     private static final boolean PLAB_DYNAMIC = false;
  90 


 108         new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_HIGH, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_HIGH, PLAB_DYNAMIC, true, true),
 109         new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_MEDIUM, OBJECT_SIZE_SMALL, GC_NUM_SMALL, YOUNG_SIZE_LOW, PLAB_DYNAMIC, true, true),
 110         new TestCase(WASTE_PCT_SMALL, PLAB_SIZE_MEDIUM, OBJECT_SIZE_HIGH, GC_NUM_HIGH, YOUNG_SIZE_HIGH, PLAB_DYNAMIC, true, false),
 111         new TestCase(WASTE_PCT_MEDIUM, PLAB_SIZE_SMALL, OBJECT_SIZE_MEDIUM, GC_NUM_MEDIUM, YOUNG_SIZE_LOW, PLAB_DYNAMIC, true, true),
 112         new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_HIGH, OBJECT_SIZE_MEDIUM, GC_NUM_SMALL, YOUNG_SIZE_HIGH, PLAB_DYNAMIC, true, true),
 113         new TestCase(WASTE_PCT_HIGH, PLAB_SIZE_HIGH, OBJECT_SIZE_SMALL, GC_NUM_HIGH, YOUNG_SIZE_LOW, PLAB_DYNAMIC, true, true)
 114     };
 115 
 116     public static void main(String[] args) throws Throwable {
 117 
 118         for (TestCase testCase : TEST_CASES) {
 119             // What we going to check.
 120             testCase.print(System.out);
 121             List<String> options = PLABUtils.prepareOptions(testCase.toOptions());
 122             options.add(AppPLABPromotion.class.getName());
 123             OutputAnalyzer out = ProcessTools.executeTestJvm(options.toArray(new String[options.size()]));
 124             if (out.getExitValue() != 0) {
 125                 System.out.println(out.getOutput());
 126                 throw new RuntimeException("Expect exit code 0.");
 127             }
 128             output = out.getOutput();
 129             checkResults(testCase);
 130         }
 131     }
 132 
 133     private static void checkResults(TestCase testCase) {
 134         long plabAllocatedSurvivor;
 135         long directAllocatedSurvivor;
 136         long plabAllocatedOld;
 137         long directAllocatedOld;
 138         long memAllocated = testCase.getMemToFill();
 139         LogParser logParser = new LogParser(output);
 140 
 141         PlabInfo survivorPlabInfo = logParser.getSpecifiedStats(GC_ID_SURVIVOR_STATS, LogParser.ReportType.SURVIVOR_STATS, FIELDS_TO_EXTRACT);
 142         PlabInfo oldPlabInfo = logParser.getSpecifiedStats(GC_ID_OLD_STATS, LogParser.ReportType.OLD_STATS, FIELDS_TO_EXTRACT);
 143 
 144         checkFields(survivorPlabInfo);
 145         checkFields(oldPlabInfo);
 146 
 147         plabAllocatedSurvivor = survivorPlabInfo.get(PLAB_USED_FIELD_NAME);
 148         directAllocatedSurvivor = survivorPlabInfo.get(PLAB_DIRECT_ALLOCATED_FIELD_NAME);
 149         plabAllocatedOld = oldPlabInfo.get(PLAB_USED_FIELD_NAME);
 150         directAllocatedOld = oldPlabInfo.get(PLAB_DIRECT_ALLOCATED_FIELD_NAME);
 151 
 152         System.out.printf("Survivor PLAB allocated:%17d Direct allocated: %17d Mem consumed:%17d%n", plabAllocatedSurvivor, directAllocatedSurvivor, memAllocated);
 153         System.out.printf("Old      PLAB allocated:%17d Direct allocated: %17d Mem consumed:%17d%n", plabAllocatedOld, directAllocatedOld, memAllocated);
 154 
 155         // Unreachable objects case
 156         if (testCase.isDeadObjectCase()) {
 157             checkDeadObjectsPromotion(plabAllocatedSurvivor, directAllocatedSurvivor, memAllocated);
 158             checkDeadObjectsPromotion(plabAllocatedOld, directAllocatedOld, memAllocated);
 159 






 160         } else {
 161             // Live objects case
 162             if (testCase.isPromotedByPLAB()) {
 163                 checkLiveObjectsPromotion(plabAllocatedSurvivor, memAllocated, "Expect that Survivor PLAB allocation are similar to all mem consumed");
 164                 checkLiveObjectsPromotion(plabAllocatedOld, memAllocated, "Expect that Old PLAB allocation are similar to all mem consumed");







 165             } else {
 166                 // All big objects should be directly allocated
 167                 checkLiveObjectsPromotion(directAllocatedSurvivor, memAllocated, "Expect that Survivor direct allocation are similar to all mem consumed");
 168                 checkLiveObjectsPromotion(directAllocatedOld, memAllocated, "Expect that Old direct allocation are similar to all mem consumed");

 169             }
 170 
 171             checkTotalPromotion(plabAllocatedSurvivor, directAllocatedSurvivor, memAllocated, "Expect that Survivor gen total allocation are similar to all mem consumed");
 172             checkTotalPromotion(plabAllocatedOld, directAllocatedOld, memAllocated, "Expect that Old gen total allocation are similar to all mem consumed");
 173         }
 174         System.out.println("Test passed!");
 175     }
 176 
 177     private static void checkTotalPromotion(long plabAllocatedSurvivor, long directAllocatedSurvivor, long memAllocated, String exceptionMessage) {
 178         // All promoted objects size should be similar to all consumed memory
 179         if (!checkDifferenceRatio(plabAllocatedSurvivor + directAllocatedSurvivor, memAllocated)) {
 180             System.out.println(output);
 181             throw new RuntimeException(exceptionMessage);
 182         }
 183     }
 184 
 185     /**
 186      * Checks that live objects were promoted as expected.
 187      * @param plabAllocated
 188      * @param totalMemAllocated
 189      * @param exceptionMessage 
 190      */
 191     private static void checkLiveObjectsPromotion(long plabAllocated, long totalMemAllocated, String exceptionMessage) {
 192         // All live small objects should be promoted using PLAB
 193         if (!checkDifferenceRatio(plabAllocated, totalMemAllocated)) {
 194             System.out.println(output);
 195             throw new RuntimeException(exceptionMessage);
 196         }
 197     }
 198 
 199     /**
 200      * Checks that dead objects are not promoted.
 201      * @param plabPromoted promoted by PLAB
 202      * @param directlyPromoted
 203      * @param memoryAllocated total memory allocated
 204      */
 205     private static void checkDeadObjectsPromotion(long plabPromoted, long directlyPromoted, long memoryAllocated) {
 206         // No dead objects should be promoted
 207         if (!(checkRatio(plabPromoted, memoryAllocated) && checkRatio(directlyPromoted, memoryAllocated))) {
 208             System.out.println(output);
 209             throw new RuntimeException("Unreachable objects should not be allocated using PLAB or directly allocated to Survivor/Old");
 210         }
 211     }
 212 
 213     /**
 214      * Checks that PLAB statistics contains expected fields.
 215      * @param info 
 216      */
 217     private static void checkFields(PlabInfo info) {
 218         if (!info.checkFields(FIELDS_TO_EXTRACT)) {
 219             System.out.println(output);
 220             throw new RuntimeException("PLAB log does not contain expected fields");
 221         }
 222     }
 223 
 224     /**
 225      * Returns true if checkedValue is less than MEM_DIFFERENCE_PCT percent of controlValue.
 226      *
 227      * @param checkedValue - checked value
 228      * @param controlValue - referent value
 229      * @return true if checkedValue is less than MEM_DIFFERENCE_PCT percent of controlValue
 230      */
 231     private static boolean checkRatio(long checkedValue, long controlValue) {
 232         return (Math.abs(checkedValue) / controlValue) * 100L < MEM_DIFFERENCE_PCT;
 233     }
 234 
 235     /**
 236      * Returns true if difference of checkedValue and controlValue is less than
 237      * MEM_DIFFERENCE_PCT percent of controlValue.
 238      *
 239      * @param checkedValue - checked value
 240      * @param controlValue - referent value
 241      * @return true if difference of checkedValue and controlValue is less than
 242      * MEM_DIFFERENCE_PCT percent of controlValue
 243      */
 244     private static boolean checkDifferenceRatio(long checkedValue, long controlValue) {
 245         return (Math.abs(checkedValue - controlValue) / controlValue) * 100L < MEM_DIFFERENCE_PCT;








 246     }
 247 
 248     /**
 249      * Description of one test case.
 250      */
 251     private static class TestCase {
 252 
 253         private final int wastePct;
 254         private final int plabSize;
 255         private final int chunkSize;
 256         private final int parGCThreads;
 257         private final int edenSize;
 258         private final boolean plabIsFixed;
 259         private final boolean objectsAreReachable;
 260         private final boolean promotedByPLAB;
 261 
 262         /**
 263          * @param wastePct
 264          * ParallelGCBufferWastePct
 265          * @param plabSize


< prev index next >