JVM消耗的本地内存与Java进程总内存使用情况

26 浏览
0 Comments

JVM消耗的本地内存与Java进程总内存使用情况

我有一个很小的Java控制台应用程序,我希望它在内存使用方面进行优化。它是在Xmx设置为仅64MB的情况下运行的。根据不同的监控工具(htop,ps,pmap,Dynatrace)显示,这个进程的整体内存使用量超过了250MB。我主要在Ubuntu 18上运行它(也在其他操作系统上测试过)。

我使用了-XX:NativeMemoryTracking java参数和Native Memory Tracking with jcmd,以找出为什么在堆之外使用了更多的内存。

当总结时,NMT显示的值与htop显示的Resident Memory大致相同。

NMT:

Total: reserved=1518873KB, committed=255877KB

htop:

\"enter

我使用了几个JVM参数来减少本地内存消耗(减少堆栈大小,将GC改为串行,类数据共享等)。

根据NMT显示的结果(malloced和mmaped都减少了),保留和已提交的内存指标总共减少了大约50MB。

NMT:

Total: reserved=1475110KB, committed=209218KB

我正在使用的所有工具(htop、ps、pmap、Dynatrace)都没有任何变化。进程使用的总内存仍然是250MB。

  1. 问题是为什么?为什么通过JVM减少本机内存使用对Java进程使用的驻留内存没有任何影响?它是否预先保留并未释放?
  2. 是否有任何其他有效减少整个Java进程的内存消耗的方法(堆之外已经优化并设置为仅64MB)?
admin 更改状态以发布 2023年5月22日
0
0 Comments

  A typical memory representation of C program consists of following sections.
  1. Text segment
  2. Initialized data segment
  3. Uninitialized data segment
  4. Stack
  5. Heap

  • JVM内存包括:JVM堆,JVM栈,JVM本地栈,程序计数器等。

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5

而JVM堆仅是Java堆部分(在C程序的内存表示中)的一部分。

0
0 Comments

NativeMemoryTracking 可能因为多种原因报告比进程的实际常驻集大小(RSS)少的承诺内存。\n

    \n

  • NMT 仅统计特定的 JVM 结构。它不会计算内存映射文件(包括已加载的 .jar 文件)或由除 libjvm 之外的库分配的内存。甚至标准类库(即 libjava)分配的本机内存也不在 NMT 报告中显示。\n
  • \n

  • 当某个东西使用标准系统分配器(malloc)分配内存,然后释放它时,这个内存并不总是返回给操作系统。系统分配器可能会将已释放的内存保留在一个池中以供将来重用,但从操作系统的角度来看,这个内存被视为已使用(因此包含在 RSS 中)。\n
  • \n

\n这篇答案和这个视频可能会让您了解什么占用了内存,以及如何分析 Java 进程的占用空间。\n这篇文章描述了一些想法(合理和极端),以减小占用空间。

0