| 
 | 1 | +/*  | 
 | 2 | + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.  | 
 | 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.  | 
 | 4 | + *  | 
 | 5 | + * This code is free software; you can redistribute it and/or modify it  | 
 | 6 | + * under the terms of the GNU General Public License version 2 only, as  | 
 | 7 | + * published by the Free Software Foundation.  | 
 | 8 | + *  | 
 | 9 | + * This code is distributed in the hope that it will be useful, but WITHOUT  | 
 | 10 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or  | 
 | 11 | + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License  | 
 | 12 | + * version 2 for more details (a copy is included in the LICENSE file that  | 
 | 13 | + * accompanied this code).  | 
 | 14 | + *  | 
 | 15 | + * You should have received a copy of the GNU General Public License version  | 
 | 16 | + * 2 along with this work; if not, write to the Free Software Foundation,  | 
 | 17 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  | 
 | 18 | + *  | 
 | 19 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA  | 
 | 20 | + * or visit www.oracle.com if you need additional information or have any  | 
 | 21 | + * questions.  | 
 | 22 | + */  | 
 | 23 | + | 
 | 24 | +package gc.z;  | 
 | 25 | + | 
 | 26 | +/*  | 
 | 27 | + * @test id=ZFakeNUMA  | 
 | 28 | + * @requires vm.gc.Z & vm.debug  | 
 | 29 | + * @library / /test/lib  | 
 | 30 | + * @summary Test ZGC graceful failure when a commit fails (with ZFakeNUMA)  | 
 | 31 | + * @run driver gc.z.TestCommitFailure -XX:ZFakeNUMA=16  | 
 | 32 | + */  | 
 | 33 | + | 
 | 34 | +import jdk.test.lib.process.ProcessTools;  | 
 | 35 | + | 
 | 36 | +import static gc.testlibrary.Allocation.blackHole;  | 
 | 37 | + | 
 | 38 | +import java.util.ArrayList;  | 
 | 39 | +import java.util.Arrays;  | 
 | 40 | +import java.util.List;  | 
 | 41 | + | 
 | 42 | +public class TestCommitFailure {  | 
 | 43 | +    static final int K = 1024;  | 
 | 44 | +    static final int M = 1024 * K;  | 
 | 45 | + | 
 | 46 | +    static final int XMS = 128 * M;  | 
 | 47 | +    static final int XMX = 512 * M;  | 
 | 48 | + | 
 | 49 | +    static class Test {  | 
 | 50 | +        static final int LARGE_ALLOC = 256 * M;  | 
 | 51 | +        static final int SMALL_GARBAGE = 256 * M;  | 
 | 52 | +        static final int SMALL_LIVE = 128 * M;  | 
 | 53 | + | 
 | 54 | +        // Allocates at least totalLive bytes of objects and add them to list.  | 
 | 55 | +        static void allocLive(List<Object> list, int totalLive) {  | 
 | 56 | +            final int largePageAllocationSize = 6 * M;  | 
 | 57 | +            for (int live = 0; live < totalLive; live += largePageAllocationSize) {  | 
 | 58 | +                list.add(new byte[largePageAllocationSize - K]);  | 
 | 59 | +            }  | 
 | 60 | +        }  | 
 | 61 | + | 
 | 62 | +        // Allocates at least totalGarbage bytes of garbage large pages.  | 
 | 63 | +        static void allocGarbage(int totalGarbage) {  | 
 | 64 | +            final int largePageAllocationSize = 6 * M;  | 
 | 65 | +            for (int garbage = 0; garbage < totalGarbage; garbage += largePageAllocationSize) {  | 
 | 66 | +                blackHole(new byte[largePageAllocationSize - K]);  | 
 | 67 | +            }  | 
 | 68 | +        }  | 
 | 69 | + | 
 | 70 | +        public static void main(String[] args) {  | 
 | 71 | +            final var list = new ArrayList<Object>();  | 
 | 72 | +            try {  | 
 | 73 | +                // Fill heap with small live objects  | 
 | 74 | +                allocLive(list, SMALL_LIVE);  | 
 | 75 | +                // Fill with small garbage objects  | 
 | 76 | +                allocGarbage(SMALL_GARBAGE);  | 
 | 77 | +                // Allocate large objects where commit fails until an OOME is thrown  | 
 | 78 | +                while (true) {  | 
 | 79 | +                    list.add(new byte[LARGE_ALLOC - K]);  | 
 | 80 | +                }  | 
 | 81 | +            } catch (OutOfMemoryError oome) {}  | 
 | 82 | +            blackHole(list);  | 
 | 83 | +        }  | 
 | 84 | +    }  | 
 | 85 | + | 
 | 86 | +    public static void main(String[] args) throws Exception {  | 
 | 87 | +        final int xmxInM = XMX / M;  | 
 | 88 | +        final int xmsInM = XMS / M;  | 
 | 89 | +        final var arguments = new ArrayList(Arrays.asList(args));  | 
 | 90 | +        arguments.addAll(List.of(  | 
 | 91 | +            "-XX:+UseZGC",  | 
 | 92 | +            "-Xlog:gc+init",  | 
 | 93 | +            "-XX:ZFailLargerCommits=" + XMS,  | 
 | 94 | +            "-Xms" + xmsInM + "M",  | 
 | 95 | +            "-Xmx" + xmxInM + "M",  | 
 | 96 | +            Test.class.getName()));  | 
 | 97 | + | 
 | 98 | +        ProcessTools.executeTestJava(arguments)  | 
 | 99 | +                .outputTo(System.out)  | 
 | 100 | +                .errorTo(System.out)  | 
 | 101 | +                .shouldContain("Forced to lower max Java heap size")  | 
 | 102 | +                .shouldHaveExitValue(0);  | 
 | 103 | +    }  | 
 | 104 | +}  | 
0 commit comments