From bb5c6dd978e19ecd3efff5c3bdeebd8a4e343fcf Mon Sep 17 00:00:00 2001 From: Miud <93437148+DajMiodu@users.noreply.github.com> Date: Sat, 7 Nov 2026 13:13:54 +0100 Subject: [PATCH 1/5] Update Aikar's flags in StartScriptGenerator Removed unnecessary flags from Aikar's configuration. --- src/components/tools/StartScriptGenerator.svelte | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/tools/StartScriptGenerator.svelte b/src/components/tools/StartScriptGenerator.svelte index 2575e0af7..20cfff7af 100644 --- a/src/components/tools/StartScriptGenerator.svelte +++ b/src/components/tools/StartScriptGenerator.svelte @@ -14,12 +14,10 @@ value: [ "-XX:+AlwaysPreTouch", "-XX:+DisableExplicitGC", - "-XX:+ParallelRefProcEnabled", "-XX:+PerfDisableSharedMem", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseG1GC", "-XX:G1HeapRegionSize=8M", - "-XX:G1HeapWastePercent=5", "-XX:G1MaxNewSizePercent=40", "-XX:G1MixedGCCountTarget=4", "-XX:G1MixedGCLiveThresholdPercent=90", @@ -27,9 +25,9 @@ "-XX:G1RSetUpdatingPauseTimePercent=5", "-XX:G1ReservePercent=20", "-XX:InitiatingHeapOccupancyPercent=15", - "-XX:MaxGCPauseMillis=200", "-XX:MaxTenuringThreshold=1", "-XX:SurvivorRatio=32", + "-XX:+UseCompactObjectHeaders", "-Dusing.aikars.flags=https://mcflags.emc.gs", "-Daikars.new.flags=true", "" /* space */, From 01253313783bdb25daa8bccf5004080c240c2ebc Mon Sep 17 00:00:00 2001 From: Miud <93437148+DajMiodu@users.noreply.github.com> Date: Sat, 7 Nov 2026 15:11:29 +0100 Subject: [PATCH 2/5] Update StartScriptGenerator.svelte Praying it works (I have no idea about the id) --- src/components/tools/StartScriptGenerator.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/tools/StartScriptGenerator.svelte b/src/components/tools/StartScriptGenerator.svelte index 20cfff7af..80a852df0 100644 --- a/src/components/tools/StartScriptGenerator.svelte +++ b/src/components/tools/StartScriptGenerator.svelte @@ -9,8 +9,8 @@ const flags: Option[] = [ { id: "none", label: "None", value: "" }, { - id: "aikar", - label: "Aikar's", + id: "paper", + label: "Paper", value: [ "-XX:+AlwaysPreTouch", "-XX:+DisableExplicitGC", From 2a5effc6ef019c59e568fcbe6a52ed22ee4cff04 Mon Sep 17 00:00:00 2001 From: Miud <93437148+DajMiodu@users.noreply.github.com> Date: Sat, 7 Nov 2026 16:04:30 +0100 Subject: [PATCH 3/5] Updated aikars-flags site updated the flags there, also changed `paper.jar` to `server.jar` --- src/content/docs/paper/admin/how-to/aikars-flags.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/paper/admin/how-to/aikars-flags.md b/src/content/docs/paper/admin/how-to/aikars-flags.md index 93a71ad07..d05136bc9 100644 --- a/src/content/docs/paper/admin/how-to/aikars-flags.md +++ b/src/content/docs/paper/admin/how-to/aikars-flags.md @@ -14,7 +14,7 @@ our **[Script Generator](/misc/tools/start-script-gen)**. ::: ```bash -java -Xms10G -Xmx10G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar paper.jar --nogui +java -Xms10G -Xmx10G -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+PerfDisableSharedMem -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:G1HeapRegionSize=8M -XX:G1MaxNewSizePercent=40 -XX:G1MixedGCCountTarget=4 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1NewSizePercent=30 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:G1ReservePercent=20 -XX:InitiatingHeapOccupancyPercent=15 -XX:MaxTenuringThreshold=1 -XX:SurvivorRatio=32 -XX:+UseCompactObjectHeaders -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar server.jar --nogui ``` :::danger[Do not allocate all of your available memory on a shared host!] From 7b154a3a019dc13d777f37a8dab7609987f9d909 Mon Sep 17 00:00:00 2001 From: Miud <93437148+DajMiodu@users.noreply.github.com> Date: Sat, 7 Nov 2026 18:15:13 +0100 Subject: [PATCH 4/5] Updated the flag explanation I did my best, also somewhat organized the order to match how they're added --- .../docs/paper/admin/how-to/aikars-flags.md | 74 ++++++++----------- 1 file changed, 32 insertions(+), 42 deletions(-) diff --git a/src/content/docs/paper/admin/how-to/aikars-flags.md b/src/content/docs/paper/admin/how-to/aikars-flags.md index d05136bc9..c88376457 100644 --- a/src/content/docs/paper/admin/how-to/aikars-flags.md +++ b/src/content/docs/paper/admin/how-to/aikars-flags.md @@ -80,10 +80,28 @@ up much space (5MB) If it does not need the memory given to it, it will not use it. The entire engine operates differently and does not suffer from too large of heaps, and this is industry-wide accepted information that under G1 to keep Xms and Xmx the same! + +2. **AlwaysPreTouch:** AlwaysPreTouch gets the memory setup and reserved at process start ensuring + it is contiguous, improving the efficiency of it more. This improves the operating systems + memory access speed. Mandatory to use Transparent Huge Pages + +3. **+DisableExplicitGC:** Many plugins think they know how to control memory, and try to invoke + garbage collection. Plugins that do this trigger a full garbage collection, triggering a massive + lag spike. This flag disables plugins from trying to do this, protecting you from their bad + code. -2. **UnlockExperimentalVMOptions:** needed for some the below options +4. **+PerfDisableSharedMem:** Causes GC to write to file system which can cause major latency if + disk IO is high - see https://www.evanjones.ca/jvm-mmap-pause.html -3. **G1NewSizePercent:** These are the important ones. You now can specify percentages of an +5. **UnlockExperimentalVMOptions:** needed for some the below options + +6. **G1HeapRegionSize=8M+:** Default is auto calculated. Super important for Minecraft, especially + 1.15, as with low memory situations, the default calculation will in most times be too low. Any + memory allocation half of this size (4MB) will be treated as "Humongous" and promote straight to + old generation and is harder to free. If you allow Java to use the default, you will be + destroyed with a significant chunk of your memory getting treated as Humongous. + +7. **G1NewSizePercent:** These are the important ones. You now can specify percentages of an overall desired range for the new generation. With these settings, we tell G1 to not use its default 5% for new gen, and instead give it 40%! **Minecraft has an extremely high memory allocation rate**, ranging to at least 800MB/second on a 30 player server! And this is @@ -97,21 +115,27 @@ up much space (5MB) we are able to slow down the intervals of young gen collections, resulting in more time for short-lived objects to die young and overall more efficient GC behavior. -4. **G1MixedGCLiveThresholdPercent:** Controls when to include regions in mixed GCs in the young +8. **G1MixedGCCountTarget=4:** Default is 8. Because we are aiming to collect slower, with less old + gen usage, try to reclaim old gen memory faster to avoid running out of old. + +10. **G1MixedGCLiveThresholdPercent:** Controls when to include regions in mixed GCs in the young GC collection, keeping old gen tidy without doing a normal old gen GC collection. When your memory is less than this percent, old gen won't even be included in 'mixed' collections. Mixed are not as heavy as a full old collection, so having small incremental cleanups of old keeps memory usage light. - + Default is 65 to 85 depending on the Java version, we are setting that to 90 to ensure we reclaim garbage in old gen as fast as possible to retain as much free regions as we can. -5. **G1ReservePercent=20:** Minecraft memory allocation rate in up-to-date versions is really insane. We +11. **G1ReservePercent=20:** Minecraft memory allocation rate in up-to-date versions is really insane. We run the risk of a dreaded "to-space exhaustion" not having enough memory free to move data around. This ensures more memory is waiting to be used for this operation. Default is 10, so we are giving another 10 to it. -6. **MaxTenuringThreshold=1:** Minecraft has a really high allocation rate of memory. Of that +12. **G1RSetUpdatingPauseTimePercent=5:** Default is 10% of time spent during pause updating RSets, + reduce this to 5% to make more of it concurrent to reduce pause durations. + +13. **MaxTenuringThreshold=1:** Minecraft has a really high allocation rate of memory. Of that memory, most is reclaimed in the eden generation. However, transient data will overflow into survivor. Initially played with completely removing survivor and had decent results, but does result in transient data making its way to old which is not good. Max Tenuring 1 ensures that we @@ -127,45 +151,11 @@ up much space (5MB) result in any 'garbage' being promoted, and just delays longer lived memory to be collected in mixed GCs. -7. **SurvivorRatio=32:** Because we drastically reduced MaxTenuringThreshold, we will be reducing +13. **SurvivorRatio=32:** Because we drastically reduced MaxTenuringThreshold, we will be reducing use of survivor space drastically. This frees up more regions to be used by eden instead. -8. **AlwaysPreTouch:** AlwaysPreTouch gets the memory setup and reserved at process start ensuring - it is contiguous, improving the efficiency of it more. This improves the operating systems - memory access speed. Mandatory to use Transparent Huge Pages - -9. **+DisableExplicitGC:** Many plugins think they know how to control memory, and try to invoke - garbage collection. Plugins that do this trigger a full garbage collection, triggering a massive - lag spike. This flag disables plugins from trying to do this, protecting you from their bad - code. - -10. **MaxGCPauseMillis=200:** This setting controls how much memory is used in between the minimum - and maximum ranges specified for your new generation. This is a "goal" for how long you want - your server to pause for collections. 200 is aiming for at most loss of 4 ticks. This will - result in a short TPS drop, however the server can make up for this drop instantly, meaning it - will have no meaningful impact on your TPS. 200ms is lower than players can recognize. In - testing, having this value constrained to an even lower number results in G1 not recollecting - memory fast enough and potentially running out of old gen triggering a full collection. Just - because this number is 200 does not mean every collection will be 200. It means it can use up to - 200 if it really needs it, and we need to let it do its job when there is memory to collect. - -11. **+ParallelRefProcEnabled:** Optimizes the GC process to use multiple threads for weak reference - checking. Not sure why this isn't default... - -12. **G1RSetUpdatingPauseTimePercent=5:** Default is 10% of time spent during pause updating RSets, - reduce this to 5% to make more of it concurrent to reduce pause durations. - -13. **G1MixedGCCountTarget=4:** Default is 8. Because we are aiming to collect slower, with less old - gen usage, try to reclaim old gen memory faster to avoid running out of old. +14. **UseCompactObjectHeaders** Shrinks object headers, doing so saves memory and cpu usage. -14. **G1HeapRegionSize=8M+:** Default is auto calculated. Super important for Minecraft, especially - 1.15, as with low memory situations, the default calculation will in most times be too low. Any - memory allocation half of this size (4MB) will be treated as "Humongous" and promote straight to - old generation and is harder to free. If you allow Java to use the default, you will be - destroyed with a significant chunk of your memory getting treated as Humongous. - -15. **+PerfDisableSharedMem:** Causes GC to write to file system which can cause major latency if - disk IO is high - see https://www.evanjones.ca/jvm-mmap-pause.html ### Transparent huge pages From 0b2857d62b31a507764d68d1a9f53f435aa6e504 Mon Sep 17 00:00:00 2001 From: Miud <93437148+DajMiodu@users.noreply.github.com> Date: Sat, 7 Nov 2026 18:23:33 +0100 Subject: [PATCH 5/5] oops, fixes Reorganize and clarify G1 GC flags documentation for better readability and understanding. --- .../docs/paper/admin/how-to/aikars-flags.md | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/src/content/docs/paper/admin/how-to/aikars-flags.md b/src/content/docs/paper/admin/how-to/aikars-flags.md index c88376457..867e1c8dd 100644 --- a/src/content/docs/paper/admin/how-to/aikars-flags.md +++ b/src/content/docs/paper/admin/how-to/aikars-flags.md @@ -119,42 +119,42 @@ up much space (5MB) gen usage, try to reclaim old gen memory faster to avoid running out of old. 10. **G1MixedGCLiveThresholdPercent:** Controls when to include regions in mixed GCs in the young - GC collection, keeping old gen tidy without doing a normal old gen GC collection. When your - memory is less than this percent, old gen won't even be included in 'mixed' collections. Mixed - are not as heavy as a full old collection, so having small incremental cleanups of old keeps - memory usage light. - - Default is 65 to 85 depending on the Java version, we are setting that to 90 to ensure we reclaim garbage - in old gen as fast as possible to retain as much free regions as we can. - -11. **G1ReservePercent=20:** Minecraft memory allocation rate in up-to-date versions is really insane. We - run the risk of a dreaded "to-space exhaustion" not having enough memory free to move data - around. This ensures more memory is waiting to be used for this operation. Default is 10, so we - are giving another 10 to it. - -12. **G1RSetUpdatingPauseTimePercent=5:** Default is 10% of time spent during pause updating RSets, - reduce this to 5% to make more of it concurrent to reduce pause durations. - -13. **MaxTenuringThreshold=1:** Minecraft has a really high allocation rate of memory. Of that - memory, most is reclaimed in the eden generation. However, transient data will overflow into - survivor. Initially played with completely removing survivor and had decent results, but does - result in transient data making its way to old which is not good. Max Tenuring 1 ensures that we - do not promote transient data to old generation, but anything that survives 2 passes of GC is - just going to be assumed as longer-lived. - - Doing this greatly reduces pause times in young collections as copying data up to 15 times in - survivor space for a tenured object really takes a lot of time for actually old memory. Ideally - the GC engine would track average age for objects instead and tenure out data faster, but that - is not how it works. - - Considering average GC rate is 10s to the upwards of minutes per young collection, this does not - result in any 'garbage' being promoted, and just delays longer lived memory to be collected in - mixed GCs. - -13. **SurvivorRatio=32:** Because we drastically reduced MaxTenuringThreshold, we will be reducing - use of survivor space drastically. This frees up more regions to be used by eden instead. - -14. **UseCompactObjectHeaders** Shrinks object headers, doing so saves memory and cpu usage. + GC collection, keeping old gen tidy without doing a normal old gen GC collection. When your + memory is less than this percent, old gen won't even be included in 'mixed' collections. Mixed + are not as heavy as a full old collection, so having small incremental cleanups of old keeps + memory usage light. + + Default is 65 to 85 depending on the Java version, we are setting that to 90 to ensure we reclaim garbage + in old gen as fast as possible to retain as much free regions as we can. + +12. **G1ReservePercent=20:** Minecraft memory allocation rate in up-to-date versions is really insane. We + run the risk of a dreaded "to-space exhaustion" not having enough memory free to move data + around. This ensures more memory is waiting to be used for this operation. Default is 10, so we + are giving another 10 to it. + +13. **G1RSetUpdatingPauseTimePercent=5:** Default is 10% of time spent during pause updating RSets, + reduce this to 5% to make more of it concurrent to reduce pause durations. + +14. **MaxTenuringThreshold=1:** Minecraft has a really high allocation rate of memory. Of that + memory, most is reclaimed in the eden generation. However, transient data will overflow into + survivor. Initially played with completely removing survivor and had decent results, but does + result in transient data making its way to old which is not good. Max Tenuring 1 ensures that we + do not promote transient data to old generation, but anything that survives 2 passes of GC is + just going to be assumed as longer-lived. + + Doing this greatly reduces pause times in young collections as copying data up to 15 times in + survivor space for a tenured object really takes a lot of time for actually old memory. Ideally + the GC engine would track average age for objects instead and tenure out data faster, but that + is not how it works. + + Considering average GC rate is 10s to the upwards of minutes per young collection, this does not + result in any 'garbage' being promoted, and just delays longer lived memory to be collected in + mixed GCs. + +15. **SurvivorRatio=32:** Because we drastically reduced MaxTenuringThreshold, we will be reducing + use of survivor space drastically. This frees up more regions to be used by eden instead. + +16. **UseCompactObjectHeaders** Shrinks object headers, doing so saves memory and cpu usage. ### Transparent huge pages