相关疑难解决方法(0)

Java使用比堆大小更多的内存(或正确的Docker内存限制大小)

对于我的应用程序,Java进程使用的内存远远超过堆大小.

容器正在运行的系统开始出现内存问题,因为容器占用的内存比堆大小多得多.

堆大小设置为128 MB(-Xmx128m -Xms128m),而容器最多占用1 GB内存.在正常情况下,它需要500MB.如果docker容器具有以下限制(例如mem_limit=mem_limit=400MB),则该进程被OS的内存不足杀死所杀死.

你能解释为什么Java进程使用比堆更多的内存吗?如何正确调整Docker内存限制?有没有办法减少Java进程的堆外内存占用?


我使用JVM中的本机内存跟踪命令收集有关该问题的一些详细信息.

从主机系统,我获得容器使用的内存.

$ docker stats --no-stream 9afcb62a26c8
CONTAINER ID        NAME                                                                                        CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
9afcb62a26c8        xx-xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.0acbb46bb6fe3ae1b1c99aff3a6073bb7b7ecf85   0.93%               461MiB / 9.744GiB   4.62%               286MB / 7.92MB      157MB / 2.66GB      57
Run Code Online (Sandbox Code Playgroud)

从容器内部,我获得进程使用的内存.

$ ps -p 71 -o pcpu,rss,size,vsize
%CPU   RSS  SIZE    VSZ
11.2 486040 580860 3814600
Run Code Online (Sandbox Code Playgroud)
$ jcmd 71 VM.native_memory
71:

Native Memory Tracking:

Total: reserved=1631932KB, committed=367400KB
-                 Java Heap (reserved=131072KB, …
Run Code Online (Sandbox Code Playgroud)

java linux memory jvm docker

95
推荐指数
3
解决办法
1万
查看次数

驻留集大小(RSS)与在Docker容器中运行的JVM的Java总提交内存(NMT)之间的差异

场景:

我有一个在docker容器中运行的JVM.我使用两个工具进行了一些内存分析:1)top 2)Java Native Memory Tracking.这些数字看起来很混乱,我试图找出导致差异的原因.

题:

对于Java进程,RSS报告为1272MB,报告的总Java内存为790.55 MB.我怎么能解释内存的其余部分1272 - 790.55 = 481.44 MB去哪了?

为什么我想在SO上查看这个问题后仍然保持这个问题的开放性:

我确实看到了答案,解释也很有道理.但是,从Java NMT和pmap -x获取输出后,我仍然无法具体映射实际驻留和物理映射的Java内存地址.我需要一些具体的解释(详细步骤)来找出导致RSS和Java Total提交内存之间差异的原因.

最高输出

在此输入图像描述

Java NMT

在此输入图像描述

Docker内存统计信息

在此输入图像描述

图表

我有一个运行48小时以上的码头集装箱.现在,当我看到一个图表包含:

  1. 给予docker容器的总内存= 2 GB
  2. Java Max Heap = 1 GB
  3. 承诺总量(JVM)=始终小于800 MB
  4. 堆使用(JVM)=始终小于200 MB
  5. 非堆使用(JVM)=始终小于100 MB.
  6. RSS =大约1.1 GB.

那么,在1.1 GB(RSS)和800 MB(Java Total committed memory)之间占用的内存是什么?

在此输入图像描述

java linux memory jvm docker

34
推荐指数
1
解决办法
1万
查看次数

使用,提交和最大堆内存的差异

我正在监视OutOfMemoryException的spark执行器JVM.我使用Jconsole连接到执行程序JVM.以下是Jconsole的快照: 在此输入图像描述

在图像中使用的内存显示为3.8G,提交的内存为8.6G,最大内存也是8.6G.任何人都可以解释使用和提交的内存或任何解释它的链接之间的区别.

java jvm memory-management apache-spark spark-streaming

32
推荐指数
2
解决办法
2万
查看次数

这些java本机内存是从哪里分配的?

JDK版本是热点8u_45

我研究了我的 java 进程的本机内存。本机内存甚至比堆消耗更多的空间。然而,有许多本机内存块让我感到困惑。例如 pmap -x 的结果:

00007f8128000000   65508   25204   25204 rw---    [ anon ]
00007f812bff9000      28       0       0 -----    [ anon ]
00007f812c000000   65508   24768   24768 rw---    [ anon ]
00007f812fff9000      28       0       0 -----    [ anon ]
00007f8130000000   65508   25532   25532 rw---    [ anon ]
00007f8133ff9000      28       0       0 -----    [ anon ]
00007f8134000000   65524   22764   22764 rw---    [ anon ]
00007f8137ffd000      12       0       0 -----    [ anon ]
00007f8138000000   65508   26456   26456 rw---    [ anon ]
00007f813bff9000 …
Run Code Online (Sandbox Code Playgroud)

java memory java-native-interface jvm pmap

8
推荐指数
1
解决办法
1384
查看次数

Java进程内存使用情况(jcmd vs pmap)

我在docker容器内的Java 8上运行了一个java应用程序.该过程启动Jetty 9服务器并部署Web应用程序.传递以下JVM选项:-Xms768m -Xmx768m.

最近我注意到这个过程耗费了大量的内存:

$ ps aux 1
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
app          1  0.1 48.9 5268992 2989492 ?     Ssl  Sep23   4:47 java -server ...

$ pmap -x 1
Address           Kbytes     RSS   Dirty Mode  Mapping
...
total kB         5280504 2994384 2980776

$ jcmd 1 VM.native_memory summary
1:

Native Memory Tracking:

Total: reserved=1378791KB, committed=1049931KB
-                 Java Heap (reserved=786432KB, committed=786432KB)
                            (mmap: reserved=786432KB, committed=786432KB) 

-                     Class (reserved=220113KB, committed=101073KB)
                            (classes #17246)
                            (malloc=7121KB #25927) 
                            (mmap: …
Run Code Online (Sandbox Code Playgroud)

java memory jvm pmap

7
推荐指数
2
解决办法
6549
查看次数

RSS 是否跟踪保留或提交的内存?

我正在 java 8 上运行不同 jvm 选项的实验,以降低 RSS:

输出(部分线程区域):

-                    Thread (reserved=130696KB -21564KB, committed=130696KB -21564KB)
                            (thread #121 -21)
                            (stack: reserved=130048KB -21504KB, committed=130048KB -21504KB)
                            (malloc=379KB -67KB #610 -105)
                            (arena=268KB +7 #240 -42)
Run Code Online (Sandbox Code Playgroud)

问题:上面输出的 RSS 将考虑什么内存,是committed还是reserved

jvm jvm-arguments

5
推荐指数
1
解决办法
1523
查看次数

Java消耗的内存超过Xmx参数

我有一个非常简单的Web服务器类(基于Java SE的HttpServer类).

当我使用此命令启动编译的类来限制内存使用时:

java -Xmx5m -Xss5m -Xrs -Xint -Xbatch Test

现在,如果我使用top命令检查内存,则表示执行我的类的Java进程使用~31MB的驻留内存.

我想知道30MB用于什么?

java jvm

5
推荐指数
1
解决办法
1933
查看次数

如何理解java.lang.management.MemoryMXBean和-Xms?

MemoryMXBean.getHeapMemoryUsage()

我有一个使用 -Xms512m -Xmx512m 运行的 jvm 进程,下面显示了该进程的 MemoryMXBean.getHeapMemoryUsage() :

    init     = 512M
    used     = 105M
    comitted = 491M
    max      = 491M
Run Code Online (Sandbox Code Playgroud)
  1. 为什么最大是491M(我预计是512M)?

此过程的MemoryMXBean.getNonHeapMemoryUsage() MemoryMXBean.getNonHeapMemoryUsage():

    init     = 2M
    used     = 25M
    comitted = 25M
    max      = 0M
Run Code Online (Sandbox Code Playgroud)
  1. 非堆(谁使用它)是什么意思?什么样的内存会被计入这个非堆呢?我只知道我们在java代码中使用的直接内存不会(我说得对吗?)

-Xms

  1. -Xms(初始堆大小)是什么意思?我曾经认为初始堆大小是jvm启动时jvm实际从os分配多少内存,但事实证明是错误的。顶部显示该 jvm 的 RES 接近 150m,但该 jvm 是使用 -Xms512M 运行的。

  2. 下面的公式正确吗(或者几乎正确-_-)?如果不是,还应该考虑什么?

total memory a jvm used = used of MemoryMXBean.getHeapMemoryUsage() 
+ used of MemoryMXBean.getNonHeapMemoryUsage()
+ the direct memory we used in application level
Run Code Online (Sandbox Code Playgroud)

任何事情都会受到赞赏!

java jvm

4
推荐指数
1
解决办法
2012
查看次数

监控java本机内存

我们正在监控 jvm 指标,如堆、元空间、线程和 gc 计数,我们能够将这些指标推送到监控服务器,如 prometheus。类似地,我们想跟踪 Java 本机内存指标(jcmd VM.sumary 的输出)。我的问题是,是否可以通过调用任何 jvm 运行时类来获取这些指标?

java monitoring jvm prometheus jcmd

4
推荐指数
2
解决办法
2270
查看次数

linux最大线程数

我使用以下代码来测试最大线程数,但这很奇怪。

import java.util.concurrent.atomic.AtomicInteger;

public class TestThread extends Thread {
    private static final AtomicInteger count = new AtomicInteger();

    public static void main(String[] args) {
        try{
            while (true) {
                (new TestThread()).start();
            }
        } catch (Error | Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Override
    public void run() {
        System.out.println(count.incrementAndGet());
        while (true)
            try {
                Thread.sleep(Integer.MAX_VALUE);
            } catch (InterruptedException e) {
                break;
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

操作系统为ubuntu:18.04,内存为4G,处理器数为2。JDK:openjdk1.8.0_252

java -Xss1m -Xms1024m -Xmx1023m TestThread

java -Xss512k -Xms1024m -Xmx1023m TestThread

java -Xss1m -Xms2048m -Xmx2048m TestThread

结果,线程数始终等于第 10000 个左右。

  1. 为什么结果是一样的。 …

java linux jvm

2
推荐指数
1
解决办法
96
查看次数