当前位置: 首页 > 知识库问答 >
问题:

如何使用java内存直方图“jmap”

韦胜泫
2023-03-14

我们的java流媒体服务器正在生产中运行,它需要约10GB的RAM才能运行,所以我们安装了32GB。内存会逐渐增加,直到达到限制并弹出内存不足异常。

由于直方图和内存转储数字与系统报告的内存使用量不匹配,我很难准确地指出随着时间的推移,哪些对象正在累积,也就是说,java进程占用的内存略多于最大20GB(因此内存不足异常是合理的),但直方图和内存转储显示总共使用了6.4GB。

process : 19.8G
Java
reported:  6.4G
---------------
unknown 
occupied
segment : 13.4G

如何在直方图中未显示的未知占用段中获取内存信息?

我用了jmap-J-d64-histo

进程映射了以下内存段,按大小排序

0x2DE000000: 13333.5MB
0x61F580000: 6666.5MB
0x7C0340000: 1020.8MB
0x7FBFF33C9000: 716.2MB
0x7FC086A75000: 196.9MB
0x7FB85C000000: 64.0MB
0x7FBAC0000000: 64.0MB
...

jmap报告的所有java对象的总大小符合0x61F58000:6666.5MB段。

我的猜测是,0x2DE000000:13333.5MB的较大部分保存泄漏的对象,因为直方图显示了该应用程序的正常内存使用情况。

有没有办法找出什么占用了直方图中没有包括的其他内存?

如何检测服务器的封闭源代码部分是否使用本机扩展来分配系统内存而不是java内存?在这种情况下,我们不会看到内存不足的异常,对吗?

这里是htop输出:

  Mem[|||||||||||||||||||||31670/31988MB]     Tasks: 87; 35 running
  Swp[||||||||||||||||||   16361/32579MB]     Load average: 39.33 36.00 34.72
                                              Uptime: 44 days, 15:08:19

  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
 3498 root       20   0 51.5G 19.8G  4516 S 151. 63.4     176h java -server -Xmx20000M -

下面是部分直方图输出:

 num     #instances         #bytes  class name
----------------------------------------------
   1:       1134597     5834904800  [B
   2:        407694      144032664  [Ljava.lang.Object;
   3:       2018132      111547480  [C
   4:        100217       71842520  [I
   5:        581934       55865664  com.wowza.wms.httpstreamer.cupertinostreaming.livestreampacketizer.CupertinoRepeaterHolder
   6:        568535       36386240  com.wowza.wms.httpstreamer.cupertinostreaming.livestreampacketizer.CupertinoTSHolder
   7:        975220       23405280  java.lang.String
   8:        967713       23225112  com.wowza.wms.amf.AMFObjChunk
   9:        621660       14919840  com.wowza.wms.httpstreamer.cupertinostreaming.livestreampacketizer.LiveStreamingCupertinoBlock
  10:        369892       11836544  java.util.ArrayList$Itr
  11:        184502       11808128  com.wowza.wms.amf.AMFPacket
  12:        329055        7897320  java.util.ArrayList
  13:         55882        6705840  com.wowza.wms.server.RtmpRequestMessage
  14:        200263        6408416  java.util.HashMap$Node
  15:         86784        6248448  com.wowza.wms.httpstreamer.cupertinostreaming.livestreampacketizer.CupertinoPacketHolder
  16:         24815        5360040  com.wowza.wms.media.h264.H264CodecConfigInfo
  17:        209398        5025552  java.lang.StringBuilder
  18:        168061        4033464  com.wowza.util.PacketFragment
  19:        119160        3813120  java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
  20:         93849        3753960  java.util.TreeMap$Entry
  21:        155756        3738144  java.lang.Long
  22:         55881        3576384  com.wowza.wms.server.RtmpResponseMessage
  23:         55760        3568640  com.wowza.util.FasterByteArrayOutputStream
  24:        130452        3130848  java.util.concurrent.LinkedBlockingQueue$Node
  25:         63172        3032256  java.util.HashMap
  26:         58747        2819856  java.nio.HeapByteBuffer
  27:         34830        2800568  [J
  28:         49076        2355648  java.util.TreeMap$AscendingSubMap
  29:         70567        2258144  com.wowza.wms.stream.livepacketizer.LiveStreamPacketizerBase$PacketizerEventHolder
  30:         55721        2228840  org.apache.mina.util.Queue
  31:         54990        2199600  java.util.HashMap$KeyIterator
  32:         58583        1874656  org.apache.mina.common.SimpleByteBufferAllocator$SimpleByteBuffer
  33:        112743        1803888  java.lang.Integer
  34:         55509        1776288  com.wowza.wms.server.ServerHandlerEvent
...
2089:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total      11078054     6454934408

java版本是:

# java -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

共有1个答案

齐财
2023-03-14

内存分为两部分

  1. 堆空间-堆上的内容,可从根目录访问

根据JMap的提取方式,perm gen可能不包括在内。不包括堆栈空间。这些可能会增加堆转储中没有看到的额外内存。

检查这些可能的原因-

  1. 您是否使用动态生成的类,导致perm gen非常大?
  2. 您是否使用了Thread Locals并在其上存储了大量数据?
  3. 由于某种原因,局部方法变量的大小可能会不断增长?

局部

如果它在本地复制,可以使用JConsole检查所有内存空间大小,以确定何时使用了这么多非堆空间。

尝试将jmap加载到内存分析器中以检查泄漏嫌疑人。它可能会显示您可能丢失的任何信息。

如需进一步阅读,请参阅这些指南

在生产设置中尝试以下设置

  1. 通过设置Xmx来增加堆大小
  2. 使用-XX:MaxPermSize=256m来增加permgenspace
  3. 设置以下标志-XX:PrintTenuringDistribution-XX:PrintGCDetails-XX:PrintGCTimeStamps-XX:HeapDumpOnOutOfMemoryError-Xloggc:/path/to/garbage。日志
  4. 在perm gen上启用GC

为了更好地诊断问题,请提供

  1. OutOfMemory错误的堆栈跟踪应该提供导致问题的信息。
  2. 您在进程开始时提供的JVM标志。
 类似资料:
  • 我想用python绘制一个非常简单的直方图。这是我的代码: 这就是结果 我怎样才能把这些条放在整数的地方呢?为什么我的图表也显示浮点数?

  • 问题内容: 我还没有使用过Redis,但我听说过它,并打算尝试将其作为缓存存储。 我听说Redis使用内存作为缓存存储数据库,那么如果我使用变量作为对象或字典数据类型来存储数据有什么区别?喜欢: Redis有什么优势? 问题答案: Redis是一个 远程 数据结构服务器。这肯定比仅将数据存储在本地内存中要慢(因为它涉及套接字往返来获取/存储数据)。但是,它也带来了一些有趣的属性: 应用程序的所有进

  • 问题内容: 我在netbeans平台上制作了App。我想绘制直方图。我有红色,绿色和蓝色的图像像素。因此,请任何人对我提出建议,如何使用该像素值绘制直方图?我的代码在下面,其中我使用图像的红色,绿色和蓝色像素值。 问题答案:

  • 我想优化直方图统计代码与霓虹灯内部。但是我没有成功。这里是c代码: 直方图统计更像是串行处理。使用neon intrinsics很难进行优化。有人知道如何优化吗?提前谢谢。

  • numpy.histogram()函数将输入数组和作为两个参数。 bin数组中的连续元素用作每个bin的边界。 Matplotlib 可以将直方图的数字表示转换为图形。 pyplot子模块的plt()函数将包含数据和数组的数组作为参数,并转换为直方图。

  • 我正在尝试使用 marplot.lib 库在 Python 中绘制直方图;但是,我一直收到此错误:“属性错误:箱必须单调增加。 这是我目前的代码: 传入的参数是信息。“信息”是一个元组列表,可能如下所示: [(4, 0.7984031936127745), (5, 0.5988023952095809), (5, 0.8739076154806492), (5, 0.736454497632824