- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于我的应用程序,Java进程使用的内存远远大于堆大小。
容器运行所在的系统开始出现内存问题,因为容器占用的内存比堆大小大得多。
堆大小设置为128 MB(-Xmx128m -Xms128m
),而容器最多占用1GB内存。正常情况下需要500MB。如果docker容器的限制低于(例如mem_limit=mem_limit=400MB
),则该进程将被操作系统的内存不足杀手杀死。
您能解释一下为什么Java进程使用的内存比堆多得多吗?如何正确调整Docker内存限制的大小?有没有办法减少Java进程的堆外内存占用量?
我使用Native memory tracking in 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
$ ps -p 71 -o pcpu,rss,size,vsize
%CPU RSS SIZE VSZ
11.2 486040 580860 3814600
$ jcmd 71 VM.native_memory
71:
Native Memory Tracking:
Total: reserved=1631932KB, committed=367400KB
- Java Heap (reserved=131072KB, committed=131072KB)
(mmap: reserved=131072KB, committed=131072KB)
- Class (reserved=1120142KB, committed=79830KB)
(classes #15267)
( instance classes #14230, array classes #1037)
(malloc=1934KB #32977)
(mmap: reserved=1118208KB, committed=77896KB)
( Metadata: )
( reserved=69632KB, committed=68272KB)
( used=66725KB)
( free=1547KB)
( waste=0KB =0.00%)
( Class space:)
( reserved=1048576KB, committed=9624KB)
( used=8939KB)
( free=685KB)
( waste=0KB =0.00%)
- Thread (reserved=24786KB, committed=5294KB)
(thread #56)
(stack: reserved=24500KB, committed=5008KB)
(malloc=198KB #293)
(arena=88KB #110)
- Code (reserved=250635KB, committed=45907KB)
(malloc=2947KB #13459)
(mmap: reserved=247688KB, committed=42960KB)
- GC (reserved=48091KB, committed=48091KB)
(malloc=10439KB #18634)
(mmap: reserved=37652KB, committed=37652KB)
- Compiler (reserved=358KB, committed=358KB)
(malloc=249KB #1450)
(arena=109KB #5)
- Internal (reserved=1165KB, committed=1165KB)
(malloc=1125KB #3363)
(mmap: reserved=40KB, committed=40KB)
- Other (reserved=16696KB, committed=16696KB)
(malloc=16696KB #35)
- Symbol (reserved=15277KB, committed=15277KB)
(malloc=13543KB #180850)
(arena=1734KB #1)
- Native Memory Tracking (reserved=4436KB, committed=4436KB)
(malloc=378KB #5359)
(tracking overhead=4058KB)
- Shared class space (reserved=17144KB, committed=17144KB)
(mmap: reserved=17144KB, committed=17144KB)
- Arena Chunk (reserved=1850KB, committed=1850KB)
(malloc=1850KB)
- Logging (reserved=4KB, committed=4KB)
(malloc=4KB #179)
- Arguments (reserved=19KB, committed=19KB)
(malloc=19KB #512)
- Module (reserved=258KB, committed=258KB)
(malloc=258KB #2356)
$ cat /proc/71/smaps | grep Rss | cut -d: -f2 | tr -d " " | cut -f1 -dk | sort -n | awk '{ sum += $1 } END { print sum }'
491080
openjdk:11-jre-slim
。
$ java -version
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment (build 11+28-Debian-1)
OpenJDK 64-Bit Server VM (build 11+28-Debian-1, mixed mode, sharing)
$ uname -a
Linux service1 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 GNU/Linux
最佳答案
Java进程使用的虚拟内存远远超出了Java堆。您知道,JVM包括许多子系统:垃圾收集器,类加载,JIT编译器等,所有这些子系统都需要一定数量的RAM才能起作用。
JVM不是RAM的唯一使用者。本机库(包括标准Java类库)也可以分配本机内存。这对于本机内存跟踪甚至是不可见的。 Java应用程序本身也可以通过直接ByteBuffers使用堆外内存。
那么,什么需要占用Java进程中的内存呢?
JVM部分(主要由本机内存跟踪显示)
Java堆
最明显的部分。这就是Java对象所在的位置。堆最多占用-Xmx
个内存。
垃圾收集器
GC结构和算法需要额外的内存来进行堆管理。这些结构包括标记位图,标记堆栈(用于遍历对象图),记忆集(用于记录区域间引用)等。其中一些是直接可调的,例如-XX:MarkStackSizeMax
,其他则取决于堆布局,例如G1区域(-XX:G1HeapRegionSize
)越大,记住的集合就越小。
GC内存开销因GC算法而异。 -XX:+UseSerialGC
和-XX:+UseShenandoahGC
具有最小的开销。 G1或CMS可能很容易使用大约总堆大小的10%。
代码缓存
包含动态生成的代码:JIT编译的方法,解释器和运行时存根。其大小受-XX:ReservedCodeCacheSize
限制(默认为240M)。关闭-XX:-TieredCompilation
以减少已编译代码的数量,从而减少代码缓存的使用。
编译器
JIT编译器本身也需要内存来完成其工作。可以通过关闭“分层编译”或减少编译器线程数(-XX:CICompilerCount
)再次减少此错误。
类加载
类元数据(方法字节码,符号,常量池,注释等)存储在称为元空间的堆外区域中。加载的类越多-使用的元空间越多。总使用量可以受-XX:MaxMetaspaceSize
(默认为无限制)和-XX:CompressedClassSpaceSize
(默认为1G)限制。
符号表
JVM的两个主要哈希表:Symbol表包含名称,签名,标识符等,而String表包含对嵌入字符串的引用。如果“本机内存跟踪”通过字符串表指示大量内存使用,则可能意味着应用程序过度调用了String.intern
。
线程数
线程堆栈还负责占用RAM。堆栈大小由-Xss
控制。默认值为每个线程1M,但是幸运的是情况还不错。 OS会延迟分配内存页面,即在首次使用时分配内存页面,因此实际内存使用量会低得多(每个线程堆栈通常为80-200 KB)。我写了script来估计有多少RSS属于Java线程堆栈。
分配本地内存的还有其他JVM部分,但是它们通常不会在总内存消耗中发挥重要作用。
直接缓冲区
应用程序可以通过调用ByteBuffer.allocateDirect
显式请求堆外内存。默认的堆外限制等于-Xmx
,但是可以用-XX:MaxDirectMemorySize
覆盖。 Direct ByteBuffers包含在NMT输出的Other
部分(或JDK 11之前的Internal
)中。
通过JMX可以看到已用直接存储器的数量,例如在JConsole或Java Mission Control中:
除了直接的ByteBuffer外,还可以有MappedByteBuffers
-映射到进程虚拟内存的文件。 NMT不会跟踪它们,但是,MappedByteBuffers也可以占用物理内存。而且没有简单的方法来限制他们可以服用多少。您可以通过查看进程内存映射来查看实际用法:pmap -x <pid>
Address Kbytes RSS Dirty Mode Mapping
...
00007f2b3e557000 39592 32956 0 r--s- some-file-17405-Index.db
00007f2b40c01000 39600 33092 0 r--s- some-file-17404-Index.db
^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
System.loadLibrary
加载的JNI代码可以分配所需的堆外内存,而无需JVM进行控制。这也涉及标准的Java类库。特别是,未关闭的Java资源可能会成为本机内存泄漏的来源。典型示例是
ZipInputStream
或
DirectoryStream
。
jdwp
调试代理)也可能导致过多的内存消耗。
mmap
系统调用)或通过使用
malloc
-标准libc分配器来请求本机内存。反过来,
malloc
使用
mmap
向操作系统请求大块内存,然后根据其自己的分配算法进行管理。问题是-此算法可能导致碎片和
excessive virtual memory usage。
jemalloc
,一种替代分配器,通常看起来比常规libc
malloc
更聪明,因此切换到
jemalloc
可能会导致占用的空间较小。
Total memory = Heap + Code Cache + Metaspace + Symbol tables +
Other JVM structures + Thread stacks +
Direct buffers + Mapped files +
Native Libraries + Malloc overhead + ...
关于java - Java使用的内存多于堆大小(或正确大小的Docker内存限制),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61671668/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!