Since pmap is a bit complex and a lot of memory mapping is anon, Here we use the vm. native_memory command in JCMD to look at each portion of JVM memory.

Native Memory Tracking: Total: reserved=6308603KB, committed=4822083KB - Java Heap (reserved=4194304KB, committed=4194304KB) (mmap: reserved=4194304KB, committed=4194304KB) - Class (reserved=1161041KB, committed=126673KB) (classes #21662) ( instance classes #20542, array classes #1120) (malloc=3921KB #64030) (mmap: reserved=1157120KB, committed=122752KB) ( Metadata: ) ( reserved=108544KB, Committed =107520KB) (used=105411KB) (free=2109KB) (waste=0KB =0.00%) (Class space:) (reserved=1048576KB, Committed =15232KB) (used=13918KB) (Free =1314KB) (waste=0KB =0.00%) - Thread (reserved=355251KB, committed=86023KB) (thread #673) (stack: reserved=353372KB, committed=84144KB) (malloc=1090KB #4039) (arena=789KB #1344) - Code (reserved=252395KB, committed=69471KB) (malloc=4707KB #17917) (mmap: reserved=247688KB, committed=64764KB) - GC (reserved=199635KB, committed=199635KB) (malloc=11079KB #29639) (mmap: reserved=188556KB, committed=188556KB) - Compiler (reserved=2605KB, committed=2605KB) (malloc=2474KB #2357) (arena=131KB #5) - Internal (reserved=3643KB, committed=3643KB) (malloc=3611KB #8683) (mmap: reserved=32KB, committed=32KB) - Other (reserved=67891KB, committed=67891KB) (malloc=67891KB #2859) - Symbol (reserved=26220KB, committed=26220KB) (malloc=22664KB #292684) (arena=3556KB #1) - Native Memory Tracking (reserved=7616KB, committed=7616KB) (malloc=585KB #8238) (tracking overhead=7031KB) - Arena Chunk (reserved=10911KB, committed=10911KB) (malloc=10911KB) - Tracing (reserved=25937KB, committed=25937KB) (malloc=25937KB #8666) - Logging (reserved=5KB, committed=5KB) (malloc=5KB #196) - Arguments (reserved=18KB, committed=18KB) (malloc=18KB #486) - Module (reserved=532KB, committed=532KB) (malloc=532KB #3579) - Synchronizer (reserved=591KB, committed=591KB) (malloc=591KB #4777) - Safepoint (reserved=8KB, committed=8KB) (mmap: reserved=8KB, committed=8KB)Copy the code

Here mmap, malloc are two different ways of allocating memory, for example:

Internal (reserved=3643KB, committed=3643KB)
                            (malloc=3611KB #8683) 
                            (mmap: reserved=32KB, committed=32KB) 
Copy the code

Indicates that a total of 3643KB is occupied by Internal resources. 3611KB is used in malloc mode and 32KB is used in mmap mode. Arenas are malloc allocated memory that is not released after code execution and will continue to be used after being placed in Arena Chunk, see MallocInternals

As you can see, Java process memory includes:

  • Java Heap: heap memory, i.e-XmxLimit the maximum heap size of memory.
  • ClassMetaspace: The metadata that loads the class and method information is called metaspace-XX:MaxMetaspaceSizeLimit the maximum size, the other is class space, by-XX:CompressedClassSpaceSizeLimit maximum size
  • Thread: Thread and thread stack occupy memory, each thread stack occupied by the size-XssLimit, but there is no limit to the total size.
  • Code: JIT just-in-time compiled (C1 C2 compiler optimized) code footprint, subject to-XX:ReservedCodeCacheSizelimit
  • GC: Garbage collection takes up memory, such as CardTable, tag count, partition records, tag GC Root, etc. It’s not restricted, it’s usually not very big.
  • The memory used by the C2 Compiler’s own code and markup is not limited and is generally not very large
  • Internal: The amount of memory used by JVMTI for command line parsing. This is unlimited and generally not very large
  • Symbol: The size occupied by the string constant pool-XX:StringTableSizeNumber limit, total memory size is not limited
  • Native Memory Tracking: The size of the Memory used by the acquisition itself, if not enabled, will not be used, this is not limited, generally not very large
  • Arena Chunk: All memory allocated via Arena. This is unlimited and usually not very large
  • Tracing: Memory occupied by all collections. If JFR is enabled, it is mainly the memory occupied by JFR. It’s not restricted, it’s usually not very big
  • Logging, Arguments, Module, Synchronizer, Safepoint, and Other are things we don’t care about.

There are two types of Memory Native Memory Tracking that are not recorded:

  • Direct Buffer: Direct memory, is mainly refers to Java nio. DirectByteBuffer when creating allocate memory. Why use off-heap memory. Usually because:

    • It can be shared between processes to reduce replication between VMS
    • Improvements to garbage collection pauses: If you are applying some long-lived and abundant objects that often start YGC or FullGC, consider putting those objects out of the heap. A large heap can affect the performance of Java applications. If off-heap memory is used, it is managed directly by the operating system (not the virtual machine). The result is to keep a small amount of in-heap memory to reduce the impact of garbage collection on the application.
    • This can improve performance of program I/O manipulation in certain scenarios. Eliminating the need to copy data from in-heap memory to out-of-heap memory.
  • Although Java Memory Mapped Files have been in the java.nio package since JDK 1.4, it is still a fairly new concept to many programmers. With the introduction of NIO, Java IO is already pretty fast, and memory-mapped files provide the fastest IO operations Java can possibly achieve, which is why high-performance Java applications should use memory-mapped files to persist data. As an important function of the NIO Mmap method provides us with the part or all of the file mapping to the ability of memory address space, and when the memory area will become dirty pages are written to the data after, the operating system will use a certain algorithm to the data written to the file, but we don’t need to care about these Java programs. This is a key advantage of memory-mapped files, because even if your program dies just after writing to memory, the operating system will still write data from memory to the file system. A more prominent advantage is shared memory, where memory-mapped files can be accessed by multiple processes at the same time, acting as low-latency shared memory.