Minecraft's default GC is ConcMarkSweepGC. Java 1.8 has a newer GC called G1GC. The downside is this new GC does a full "stop the world" collection every 5-10 minutes. I was able to prevent this with some tweaking. G1GC's default lazy memory management is now more aggressive than ConcMarkSweepGC. When you load Forge you'll see what I mean: it keeps more stuff in memory but still cleans that memory quite often.
Not since around 1.13; the default JVM arguments were changed to the following so if you are still using the older JVM arguments then you must be using a 3rd party launcher or a very old profile with edited arguments (otherwise they should automatically update when Mojang updates them, which is also an argument against changing them):
Also, modern/modded Minecraft only needs such arguments because it is coded so poorly that it allocates and discards hundreds of megabytes of memory per second, more than my own highly optimized modded version which was coded to minimize object creation and unnecessary wrappers/encapsulation/etc uses in total, even at maximum settings in a demanding environment, which runs perfectly fine for hours with these arguments, which are based on the older default arguments except I reduced memory to 512MB and removed CMSIncrementalMode (which only makes sense on single-core CPUs so I don't know why it used to be so popular); maybe G1GC would work better but I've never seen a reason to change it:
Oh! I had no idea Microsoft updated the arguments. Yes, I am using a third-party launcher. Not by choice. Microsoft's launcher plain does not work on my computer due to my VPN configuration.
Those G1GC arguments are horrid. I ran a 3x memory boost version on my test world (2g was not enough for my mods). Average FPS was similar but 1% lows were happening every 1-2 seconds. That was worse than ConcMarkSweepGC which would peg the renderer once every 20-40 seconds.
Here's why:
MaxGCPauseMillis is useless. 50ms is 20fps and it's a soft target, right? No. 50ms means it'll try to make the GC pause for that duration maximum - it can then do another GC 1ms later. You're not really maintaining 50fps.
Setting a fixed heap size is also pointless because they left AdaptiveSizePolicy enabled (it's enabled by default). So G1GC will literally ignore it. I mean, it does take that flag into consideration, but if you dump enough garbage it'll go right over the limit. That's why it's called adaptive. Ofc the 20fps target will prevent that mistake from being too obvious - but eventually it'll dig into the reserve percent with every sweep. That means excessively large GCs.
The only flag making a positive difference is G1NewSizePercent. If you notice Microsoft used a target that's half of mine. That matters because as you say, MC discards a lot of memory, which means you're going to have allocation problems after the game has run for a while. I didn't test it for more than 5 minutes but I assume longer gaming sessions would encounter either full GCs or excessive GC sweeps.
Edit: I've updated my OP to reflect the information you've provided. Thank you!
Also, I notice that 1.8 Optifine thread mentions using a "controllable GC."
Guess they didn't know G1GC has way more config options than other GC models. Makes sense, Java 1.8 and MC 1.8 were both released from beta in 2014.
<deleted>
Not since around 1.13; the default JVM arguments were changed to the following so if you are still using the older JVM arguments then you must be using a 3rd party launcher or a very old profile with edited arguments (otherwise they should automatically update when Mojang updates them, which is also an argument against changing them):
Also, modern/modded Minecraft only needs such arguments because it is coded so poorly that it allocates and discards hundreds of megabytes of memory per second, more than my own highly optimized modded version which was coded to minimize object creation and unnecessary wrappers/encapsulation/etc uses in total, even at maximum settings in a demanding environment, which runs perfectly fine for hours with these arguments, which are based on the older default arguments except I reduced memory to 512MB and removed CMSIncrementalMode (which only makes sense on single-core CPUs so I don't know why it used to be so popular); maybe G1GC would work better but I've never seen a reason to change it:
See also: Minecraft 1.8 has so many performance problems that I just don't know where to start with.
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
Oh! I had no idea Microsoft updated the arguments. Yes, I am using a third-party launcher. Not by choice. Microsoft's launcher plain does not work on my computer due to my VPN configuration.
Those G1GC arguments are horrid. I ran a 3x memory boost version on my test world (2g was not enough for my mods). Average FPS was similar but 1% lows were happening every 1-2 seconds. That was worse than ConcMarkSweepGC which would peg the renderer once every 20-40 seconds.
Here's why:
MaxGCPauseMillis is useless. 50ms is 20fps and it's a soft target, right? No. 50ms means it'll try to make the GC pause for that duration maximum - it can then do another GC 1ms later. You're not really maintaining 50fps.
Setting a fixed heap size is also pointless because they left AdaptiveSizePolicy enabled (it's enabled by default). So G1GC will literally ignore it. I mean, it does take that flag into consideration, but if you dump enough garbage it'll go right over the limit. That's why it's called adaptive. Ofc the 20fps target will prevent that mistake from being too obvious - but eventually it'll dig into the reserve percent with every sweep. That means excessively large GCs.
The only flag making a positive difference is G1NewSizePercent. If you notice Microsoft used a target that's half of mine. That matters because as you say, MC discards a lot of memory, which means you're going to have allocation problems after the game has run for a while. I didn't test it for more than 5 minutes but I assume longer gaming sessions would encounter either full GCs or excessive GC sweeps.
Edit: I've updated my OP to reflect the information you've provided. Thank you!
Also, I notice that 1.8 Optifine thread mentions using a "controllable GC."
Guess they didn't know G1GC has way more config options than other GC models. Makes sense, Java 1.8 and MC 1.8 were both released from beta in 2014.
Someone appears to have moved my mod to "support." I'm not asking for support! Guess I'll delete my post.