1

I have a Java app which use a lot of memory off heap, more than expected. Native memory tracking says that the app uses 14 GB but from the informations obtained with top the app uses 25.6 GB of virtual memory. What is this difference due to?

> jcmd 1 VM.native_memory summary
1:

Native Memory Tracking:

Total: reserved=14160512KB, committed=12564552KB
-                 Java Heap (reserved=10485760KB, committed=10485760KB)
                            (mmap: reserved=10485760KB, committed=10485760KB) 
 
-                     Class (reserved=1169595KB, committed=134571KB)
                            (classes #18900)
                            (  instance classes #17854, array classes #1046)
                            (malloc=2235KB #47971) 
                            (mmap: reserved=1167360KB, committed=132336KB) 
                            (  Metadata:   )
                            (    reserved=118784KB, committed=118088KB)
                            (    used=115663KB)
                            (    free=2425KB)
                            (    waste=0KB =0.00%)
                            (  Class space:)
                            (    reserved=1048576KB, committed=14248KB)
                            (    used=13795KB)
                            (    free=453KB)
                            (    waste=0KB =0.00%)
 
-                    Thread (reserved=269333KB, committed=27681KB)
                            (thread #261)
                            (stack: reserved=268244KB, committed=26592KB)
                            (malloc=420KB #1567) 
                            (arena=669KB #520)
 
-                      Code (reserved=253419KB, committed=97975KB)
                            (malloc=5735KB #26933) 
                            (mmap: reserved=247684KB, committed=92240KB) 
 
-                        GC (reserved=347341KB, committed=183501KB)
                            (malloc=19653KB #50171) 
                            (mmap: reserved=327688KB, committed=163848KB) 
 
-                  Compiler (reserved=1788KB, committed=1788KB)
                            (malloc=2020KB #2691) 
                            (arena=18014398509481751KB #5)
 
-                  Internal (reserved=5265KB, committed=5265KB)
                            (malloc=5233KB #3983) 
                            (mmap: reserved=32KB, committed=32KB) 
 
-                     Other (reserved=1589357KB, committed=1589357KB)
                            (malloc=1589357KB #49387) 
 
-                    Symbol (reserved=29460KB, committed=29460KB)
                            (malloc=26703KB #274450) 
                            (arena=2757KB #1)
 
-    Native Memory Tracking (reserved=7838KB, committed=7838KB)
                            (malloc=502KB #7072) 
                            (tracking overhead=7336KB)
 
-               Arena Chunk (reserved=865KB, committed=865KB)
                            (malloc=865KB) 
 
-                   Logging (reserved=5KB, committed=5KB)
                            (malloc=5KB #191) 
 
-                 Arguments (reserved=18KB, committed=18KB)
                            (malloc=18KB #487) 
 
-                    Module (reserved=259KB, committed=259KB)
                            (malloc=259KB #2307) 
 
-              Synchronizer (reserved=205KB, committed=205KB)
                            (malloc=205KB #1651) 
 
-                 Safepoint (reserved=4KB, committed=4KB)
                            (mmap: reserved=4KB, committed=4KB) 

and top

> top
Tasks:   3 total,   1 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s): 16.5 us,  4.1 sy,  0.0 ni, 79.1 id,  0.0 wa,  0.0 hi,  0.4 si,  0.0 st
MiB Mem :  64432.6 total,  36088.6 free,  24722.6 used,   3621.5 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.  38616.4 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                                                                          
    1 loro      20   0   25.6g  12.2g  22144 S 509.8  19.4   2066:35 java                                                                                                                                                             
 2350 root      20   0    5748   3596   3068 S   0.0   0.0   0:00.06 bash                                                                                                                                                             
 2926 loro      20   0    9804   3540   3052 R   0.0   0.0   0:00.03 top  

The app runs on jdk11 with

java;-server;-XX:+UnlockExperimentalVMOptions;-XX:+UseShenandoahGC;-XX:ShenandoahGCHeuristics=compact;-XX:+AlwaysPreTouch;-XX:+UseNUMA;-XX:-UseBiasedLocking;-Xms10G;-Xmx10G;-XX:+DoEscapeAnalysis;-XX:+PrintConcurrentLocks;-verbose:gc;-XX:+PrintGCDetails;-XX:NativeMemoryTracking=detail;-XX:+UseContainerSupport;-XshowSettings:vm;-XX:MaxRAMPercentage=90;-XX:InitialRAMPercentage=50;-XX:+PrintFlagsFinal;-jar;/home/loro/service.jar

Lorenzo Belli
  • 1,767
  • 4
  • 25
  • 46
  • Can this be an Allocator Issue as briefly covered [here](https://stackoverflow.com/questions/53451103/java-using-much-more-memory-than-heap-size-or-size-correctly-docker-memory-limi/53624438) ? – Lorenzo Belli Aug 10 '20 at 16:07

1 Answers1

0

This does not look like an issue. I have seen this many times and at the beginning of my career I used to be worried too. The field you should check when it comes to memory consumption is called RES because it means the actual amount of physical memory taken by your process.

This behaviour is described as something expected in this article provided by RedHat https://access.redhat.com/solutions/296313. I have a free account so I can read it, if you do not have I am quoting this here.

From the man page for top, VIRT is the total amount of virtual memory used by the task. It includes all code, data and shared libraries plus pages that have been swapped out. VIRT also includes pages that have been allocated but not used for anything yet. Any page in this state is mapped to the kernel Zero Page so it shows up in VIRT but doesn't actually consume any memory.

To check actually physical memory used by the processes check RES field in Top output instead of VIRT.

Its more of kernel behaviour and whenever system demands memory its can be used by freeing cached memory.

I hope this can help you with this confusing thing.

rcastellcastell
  • 387
  • 1
  • 7