How is it decided that how much physical memory is to be allocated to java heap?

对着背影说爱祢 提交于 2020-06-13 00:47:06

问题


I have machine with 16G RAM. I run a java application with arguments -Xms9G -Xmx9G. When I run top command I see that my java process is taking 13.8g VIRT, but only 4.6g of RES.

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 5019 root      20   0 13.8g 4.7g  18m S  0.7 30.7   3:28.39 java                                     

On running pmap command, I see that only ~3.9g of heap is present as RES, rest 5.7g is in virtual.

Address           Kbytes     RSS   Dirty Mode   Mapping
0000000580000000 9452384 4074228 4074228 rw---    [ anon ]

Upon monitoring HPCUR with jvmtop, I observe that the GC is triggered when the HPCUR reaches about 3g.

PID MAIN-CLASS        HPCUR HPMAX NHCUR NHMAX    CPU     GC    VM USERNAME   #T DL
 5019 .1-SNAPSHOT.jar  408m 9216m  192m   n/a  0.25%  0.00% O8U20   webapp  823

I observe that the RES for the process increases gradually, heap memory in RES (by pmap) also increases gradually too. As a result GC threshold increases.

I have several questions about this behavior.

  1. Is only the heap that is present in RES used, and not the VIRT?
  2. If I have allotted 9G min heap (-Xms), then initially why only 3.9g RES is allotted. Isn't this same as keeping -Xms low? What is the point of keeping -Xms=-Xmx then?
  3. On what basis is it decided that how much heap should be in RES? Read somewhere that its managed by OS, but any rough logic?
  4. Any way to make sure, that the allotted heap is actually used?

回答1:


  1. Yes HEAP is RES (as long as it fits in main memory)
  2. This answer suggests that -Xms is a hint to GC at what point a full garbage collection is necessary. Testing with my local JVM I can confirm that it does not immediately reserve the memory. What you gain is that your JVM does not block a lot of unused memory but will reach you lower bound faster as there are less GC runs.
  3. Answered by 1. : RES always contains all of HEAP
  4. My understanding is that your options will achieve what you intend to. Your application will grab 9GB of memory and then start garbage collection more frequently. There are other options like MinHeapFreeRatio and options that depend on the gargbage collector used if you need more optimization.

Did you print GC logs and verify that something is wrong? If you see a lot of GC runs on application startup before 9G is reached I would look further. If there is hardly any GC run before hitting 9G I would say everything is fine.




回答2:


  • VIRT denotes Virtual memory - this is the entire reserved address space of the process. RSS is the resident set size - the portion of the virtual address space allocated in physical RAM. For any address range (not only the heap) RSS is the subset of VIRT, possibly complete or empty. Seems like you already explored pmap - for each virtual address range it shows the exact amount of physically allocated memory (RSS).
  • OS allocates physical pages lazily on the first access. That's why even committed memory is not the part of RSS until the corresponding pages are read or written to. The fact that the large portion of heap is not in RSS means that this part of the heap has never been touched. See also this question.
  • There is a JVM option -XX:+AlwaysPreTouch that forcibly touches every page of the heap thus making it the part of RSS. Try java -Xms9G -Xmx9G -XX:+AlwaysPreTouch.


来源:https://stackoverflow.com/questions/56334831/how-is-it-decided-that-how-much-physical-memory-is-to-be-allocated-to-java-heap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!