Jump to content

  • Curse Sites
Become a Premium Member! Help
Latest News Article

Minecraft, Java, Memory, and Out of Memory

out of memory java memory heap texturepacks 1.3 xmx

  • Please log in to reply
2 replies to this topic

#1

2metragluposti

Posted 28 July 2012 - 06:24 AM

Hello.



I'll try to shed some light as to why Minecraft can eat all your memory and cause "Out of memory", even on systems with 8GB+ and maximum size set to a specific value lower than your memory.

First and foremost, I am using Minecraft 1.3prerelease .JAR!!!! , 4GB ram + 4GB pagefile, 64x Windows 7 SP1, 64x Java 1.7.

Also, always test your memory settings in Minecraft with the F3. If it didn't change, something is wrong.

Java and Memory 101: http://blogs.vmware....va-process.html




Minecraft is set by default to have 1GB maximum limit of heap memory for it's use, and I think the starting heap size is the same.

-Xmx command sets maximum usable heap aka Java's memory for Minecraft. When max heap is reached, and more memory is needed, you will get the "Out of memory" error. This occurs with let's say 512x HD Texturepacks, since they can't load fully.  Increase the heap, and you will be able to load your textures.

Also, -Xmx will not be the maximum memory used by Minecraft, so that can cause problems because the "Java and Minecraft inside the heap" can go over Xmx value, and thus close or over your available system memory, causing OOM or stuttering on high end systems. See link above for details. It shouldn't be much more, BUT Minecraft is weird in that aspect and I will go in that later.

-Xms just allocates starting heap size. When loading the game the heap memory is expanded by itself up to the Xmx value. This is IMO unnecessary command to have, but it perhaps-might-maybe-I'm not sure speed up the loading process, since the empty heap memory is already prepared. Set it from half up to full Xmx value IF it makes a difference. Note that this will impact garbage collection discussed below.

On machines with low specs, RAM especially, you should reduce the Xmx value, because it could eat all of your precious system resources, and thus causing system wide stuttering or OOM. Also, Xms, the starting heap size must be same as Xmx, or lower. My advice is not to use Xms at all in these scenarios, and set Xmx to 256-512MB, depending on your graphical settings.





Now that we know what heap is, let's go to Java's new memory management. The empty heap expands according to the Minecraft needs. Part of it becomes the used heap, and part of it lays empty, to be filled or expanded later. So when the heap grows, up to Xmx, it will remain at that size and will use your system memory. The used heap can drop, as the game deallocates memory, but the heaps overall size after growth won't shrink. Used heap - rises and falls. Heap - rises when needed and stays. Heap's last size = approx. system memory used.

Scenario: game starts loading. Xmx is 2GB. Xms is not defined. The game expands to 300mb, 1200mb, and stops and 1300mb of used heap. The heap size is now approx. 1500MB, because heap = used heap plus empty to be used heap. Game may now free some used heap and drop to let's say 750MB, but 1500MB are taken from your system memory + some extras as stated earlier, so the game will now take approx 1800MB. That's almost your Xmx value, but it was enough to load your textures and to play the game.

The conclusion is that we now have 750MB that the game is actually using, and 1050MB that is simply unused and unavailable to your system. Now, the game will probably jump back to 1000MB+ used heap when you actually start playing, but there will always be that extra empty unused heap that is unavailable to your system and not necessary for Minecraft.

Now this is personal preference, but if you have 2GB of RAM (note that Xmx 2gb is too big in that case), you are playing the game with 1000-1300MB used, you have wasted approx. 500MB because the heap stayed at 1800MB. In that case, your system memory is low, and alt-tabbing or opening something in the background will be sluggish, because have almost used your 2GB of RAM. It might even make Minecraft stutter, because the system is begging for memory for itself and services/background stuff. And things will go into the hard disk - the pagefile, making things even more sluggish.





Enter Java's Garbage, you gon' get collected real good.

Java's Garbage Collectors do two things, depending on which one is used.

1.) They reduce used heap, which in turn means more free heap, so heap won't rise and use more system memory. Note that this is a very crafty technique and doesn't mean it will magically free used heap. A lot of mechanisms are at play here, and used heap will be let's say optimized, instead of simply reduced.

2.) They can reduce the free heap! That means more memory for your system! More fresh breathing air! But this needs to be stated as a command, and they COULD potentially cause stutters every now and then when they collect garbage and reduce the heap. This might be really noticable, and might not even be noticed at all. Testing this is a must. Also, don't expect magic reductions to happen here. Might prevent memory leaks if you look at the idea of what they are doing, but this is a wild guess.

Note that only 2, perhaps 3 implementations of Garbage Collectors can reduce heap.

They are the serialGC: -XX:+UseSerialGC , the serial+parallel for different generations: -XX:+UseParNewGC  and the newest implementation that works differently, but might yield same results is -XX:+UseG1GC

AFAIK latest Java uses pure parallel or CMS collectors. They DON'T reduce heap size. On the other hand, they are least intrusive when they collect used space, so they should not cause stuttering.

So, if you need to have some breathing space, you should give the non-default collectors a try, especially UseParNewGC. Do try UseG1GC first.

(UseG1GC >) UseParNewGC > UseSerialGC

UseSerialGC and UseParNewGC, and maybe UseG1GC can be made more aggressive on the heap manipulation. With -XX:MaxHeapFreeRatio=10 if there is more than 10% space between unused heap and used heap, unused free heap will be reduced. The default is 70% so it's useless for Minecraft. With -XX:MinHeapFreeratio=10 (can't be bigger than MaxFreeHeapRatio) if there is less than 10% between used and unused heaps, the free heap is increased. Default if 40% which makes drastic free heap expansions.

Note that collectors behave differently depending on the number of your cores and CPU speed. I don't have any advice to give you here, I'm assuming 2xcores are a standard nowadays.

Garbage Collectors collect as they please. This can be more or less influenced, but I'm not very knowledgeable at that. So this might discourage any usage of GC that reduce heap, as I can't say when will they free your memory. Do note that I will try to learn how to evoke a full garbage collection from another program to Minecraft and post here.

Also, Xms apparently blocks heap reduction below it's value. I really don't know if dynamic free heap allocation slows things down noticeably vs. already Xms free heap allocated, but IMO it shouldn't be noticeable, and all of the free heap can be manipulated.

Then again if Xms = half Xmx means that used heap will most probably always be in or above the Xms value, aka that heap would be used always anyways, thus skipping a part of dynamic allocation of free heap and "speeding" things up to that Xms value. This seems like a good option to try on most systems.

And if Xms=Xmx, GC won't free heap. But this might give the best results if you have a lot of memory with a good Xmx value that gives enough to Minecraft, and isn't so close to your max system memory, and you don't need non-default collectors to reduce free heap and free memory. Terms dedicated or high end pop up here.




To recap:
Heap = available "memory" for the game. It resides in Java's Virtual Machine, which is loaded in your RAM.
Heap = free heap (to be filled with used) + used heap (used by game)
Heap once expanded stays and takes system memory.
Heap + extra Java memory = Minecraft's "real" memory usage*
*see discussion below
-Xmx = max heap value, used to avoid OOM, but setting too much might cause OOM or chokes your system
-Xmx is NOT the maximum memory value Minecraft will use. It always takes some extra space above Xmx (half a gig with HD textures for me, which needed 2.5GB themselves, totaling a 3gb usage)
-Xms = starting free heap value. Can be skipped IMO. Try with half of -Xmx or full -Xmx value. Affects GC, and maybe loading speed
Garbage Collectors do or do not reduce the free heap. Can give more free system memory, unchoking the system
Garbage Collectors that are non-default MIGHT cause stutters when they clean, but this frees memory
Garbage Collectors don't reduce heap below -Xms value

Example for .jar, might work for .exe (skip -cp, minecraftL.jar and launcherframe parts and use .exe?):

java -XX:+UseParNewGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=10 -Xmx2500M -Xms1000M -cp MinecraftL.jar net.minecraft.LauncherFrame
pause




*the discussion below:

Since I'm new here, I don't have much cred, but I'd be happy if a developer read this part.

Minecraft's memory usage is erratic. It should be, assuming I'm using HD textures, 512x infact, heap size reached (possibly up to maximum defined value, which is 1gb by default), plus extra Java memory which shouldn't be that much (as shown in the link at the top). However, I will post my measurings of Java and the game that I posted on another forum, asking you the same question:

http://stackoverflow...memory-overhead

Register or log in to remove.

#2

denden216
  • Location: United Kingdom.

Posted 28 July 2012 - 08:26 AM

Well for anyone that doesn't know how to give Java more ram I made a quick and simple video for you :)

Video link:

Posted Image


#3

gerbil
    gerbil

    Support Guru

  • Members
  • 4913 posts

Posted 28 July 2012 - 01:48 PM

Quote

extra Java memory which shouldn't be that much (as shown in the link at the top)

You don't know that.

In general, extra Java memory could be almost ANY amount depending upon the application and what it does.
The extra memory is dependent upon # of threads launched, the JVM's implementation, the native OS (e.g. Window's per process and per thread overhead, versus OS X per process / thread overhead), and the APIs that the application uses that end up in native / OS calls.

In specific, the Minecraft process size is very dependent upon the specific video driver being used and how it manages memory.