30

MaxRAM:

based on the amount of memory on the machine. The proportion of memory to use for the heap is controlled by the command-line options InitialRAMFraction and MaxRAMFraction [...] The value of MaxRAM is platform-dependent.

Xmx:

-Xmxn Specify the maximum size, in bytes, of the memory allocation pool. This value must a multiple of 1024 greater than 2MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is 64MB. The upper limit for this value will be approximately 4000m on Solaris 7 and Solaris 8 SPARC platforms and 2000m on Solaris 2.6 and x86 platforms, minus overhead amounts.

As I understand both define heap size. No? What is recommended to use: Xmx or MaxRAM? If I use both which one ovverides another?

trincot
  • 317,000
  • 35
  • 244
  • 286
Cherry
  • 31,309
  • 66
  • 224
  • 364

1 Answers1

38

-Xmx specifies the precise upper limit for the heap. It is the preferred way to set the heap size.

-XX:MaxRAM does not define the heap size directly. Instead this parameter overrides the actual amount of physical RAM when calculating the heap limits basing on ergonomics.

If -Xmx is set, MaxRAM is never used. Otherwise the maximum heap size is estimated1 as

MaxHeapSize = MaxRAM * MaxRAMPercentage / 100% (default MaxRAMPercentage=25)

1 The actual algorithm is a bit more complicated and depends on other parameters.

apangin
  • 92,924
  • 10
  • 193
  • 247
  • 3
    _It is the preferred way to set the heap size_, unless this is started in a container, right? in that case `InitialRAMPercentage` and `MaxRAMPercentage` would be your best bet. Am I correct? – Eugene Nov 15 '19 at 16:27
  • 1
    @Eugene Preferences are subjective :) In my opinion, the heap size should *always* be set explicitly. Especially in a container. I can justify this claim from our own experience in running hundreds Java services in 12000+ containers, but this would be too long for a comment. – apangin Nov 15 '19 at 16:57
  • 5
    My presentation [Memory Footprint of a Java Process](https://vimeo.com/364039638) may give a hint. In short: there are already too many factors that affect the footprint, so you hardly want to add one more uncontrollable variable in the memory equation. – apangin Nov 15 '19 at 17:05
  • 3
    very interesting point, the only thing I don't like is the fact that if you specify `-Xmx` and `-Xms`, you would also need to specify `-m` for `docker` correctly. If you are involved in a company like mine, producing the docker images does not mean you will have control of where and by whom they are started; I should have said this explicitly in the beginning, I guess. – Eugene Nov 15 '19 at 17:12
  • 1
    @Eugene *"if you specify -Xmx and -Xms, you would also need to specify -m for docker correctly"* - yes, and that's fine, because these parameters are not very much related, even though JDK developers are trying to convince users that so called "Java container support" feature does all the magic. In reality, it does nothing but a kind of `Xmx = cgroup_mem_limit * MaxRAMPercentage / 100` – apangin Nov 15 '19 at 17:43
  • *"does not mean you will have control of where and by whom they are started"* - right, but you probably have control over the image contents - that is, the application. So, you know best how much memory your application requires, regardless of the external limits. If the application requirements are configurable, it's perfectly fine to specify the heap size, for example, through an environment variable. – apangin Nov 15 '19 at 17:50
  • 1
    I am confused about your point a bit. I agree with this : `Xmx = cgroup_mem_limit * MaxRAMPercentage / 100` (roughly), but isn't that the entire point? If you don't specify `Xmx` directly, _but_ specify `docker -m` _and_ `MaxRAMPercentage=80.0` for example - you would get 80% of whatever `-m` was provided; unless I am missing something obvious here. – Eugene Nov 15 '19 at 18:36
  • it would be much more complicated if I say `-Xmx2G`, but docker says `-m1g`, isn't it? – Eugene Nov 15 '19 at 18:38
  • 1
    @Eugene Typically container settings needs to depend on the application requirements, not vice versa. I.e. "my app requires 2G heap, please run it in a container with strictly more than 2G quota". If I run it with -m1g, the app won't work anyway, no matter if Xmx adapts to the container limit or not. – apangin Nov 16 '19 at 14:01
  • Of course, there are apps that may work with less RAM, but benefit from more RAM (e.g. caches, databases, download services etc.) We have a lot of such services, but even in these cases they usually need a constant heap while utilizing more off-heap memory through ByteBuffers, page cache, tmpfs and so on. – apangin Nov 16 '19 at 14:01
  • the video is stunning! two things : 1) I wish it were in russian 2) you have a very tight audience for the things you present, I admit I only understood (or knew) about 50% of the things. much appreciated the time and link. – Eugene Nov 18 '19 at 03:45
  • @Eugene Thanks. There is [Russian version of this talk](https://www.youtube.com/watch?v=kKigibHrV5I), too. – apangin Nov 18 '19 at 08:30