【问题标题】:How to find Java Heap Size and Memory Used (Linux)?如何查找 Java 堆大小和使用的内存 (Linux)?
【发布时间】:2012-09-29 15:19:24
【问题描述】:

如何在 Linux 上通过命令行检查 Java 应用程序的堆大小(和已用内存)?

我已经通过 jmap 尝试过。但它提供信息。关于 Eden/ PermGen 等内部内存区域,这对我没有用。

我正在寻找类似的东西:

  • 最大内存:1GB
  • 最小内存:256 MB
  • 堆内存:700 MB
  • 已用内存:460 MB

就是这样。我知道我可以在 JConsole 等中看到这一点,但我需要通过命令行来完成。 (无法启用 JMX 等)

【问题讨论】:

    标签: java linux performance memory heap-memory


    【解决方案1】:

    每个 Java 进程都有一个pid,您首先需要使用jps 命令找到它。

    获得 pid 后,您可以使用 jstat -gc [insert-pid-here] 查找垃圾收集堆行为的统计信息。

    • jstat -gccapacity [insert-pid-here] 将提供有关内存池生成和空间容量的信息。

    • jstat -gcutil [insert-pid-here] 将显示每一代的利用率占其容量的百分比。有助于一目了然地了解使用情况。

    请参阅 Oracle 网站上的 jstat docs

    【讨论】:

    • 是否有建议使用jstat 的哪些选项来验证JVM 的整体内存使用情况?假设您使用Xms=4gXmx=4g 启动JVM,并且您想查看其中已经使用了多少内存?
    • "jstat -gcutil 250 N" 对于以 250 毫秒间隔采集 N 个样本并将输出显示为相应空格的百分比非常有用。谢谢。
    • 值得注意的引用来自jstatOracle Java 8 手册page:This command is experimental and unsupported
    • awk 'print {$3+$4+$6+$8}' 可以在 Java 8 的 jstat 列上打印汇总使用情况
    • 其他答案有问题,但基本的ps -ef | grep java 向我展示了 vm args,在我的情况下,它包括 -Xmx 值,这正是我所需要的。
    【解决方案2】:

    此命令以字节为单位显示配置的堆大小。

    java -XX:+PrintFlagsFinal -version | grep HeapSize
    

    它也适用于 EC2 上的 Amazon AMI。

    【讨论】:

    • 这并没有回答问题,它专门询问如何检查进程的堆使用情况。此处的命令列出了所有进程中的 JVM 默认值。
    • 然而,这对我来说是一个非常有帮助的答案,我通过谷歌搜索来到这个页面,了解如何找到全局堆大小。
    • @jumping_monkey 不是间接的,不正确的。如果您说的是真的,则应编辑答案,或者您可以随意添加新答案。
    • 最初的问题标题含糊不清,应该保留为列出的答案。此外,回答配置问题是谷歌上最容易找到的答案。
    【解决方案3】:

    jvmtop 是一个命令行工具,可提供包括堆在内的多个指标的实时视图。

    VM 概览模式的示例输出:

     JvmTop 0.3 alpha (expect bugs)  amd64  8 cpus, Linux 2.6.32-27, load avg 0.12
     http://code.google.com/p/jvmtop
    
      PID MAIN-CLASS      HPCUR HPMAX NHCUR NHMAX    CPU     GC    VM USERNAME   #T DL
     3370 rapperSimpleApp  165m  455m  109m  176m  0.12%  0.00% S6U37 web        21
    11272 ver.resin.Resin [ERROR: Could not attach to VM]
    27338 WatchdogManager   11m   28m   23m  130m  0.00%  0.00% S6U37 web        31
    19187 m.jvmtop.JvmTop   20m 3544m   13m  130m  0.93%  0.47% S6U37 web        20
    16733 artup.Bootstrap  159m  455m  166m  304m  0.12%  0.00% S6U37 web        46
    

    【讨论】:

    • 它确实是一个很棒的工具,有点像 htop,但有来自 jstat 的指标。感谢@MRalwasser 的建议。
    • 由于 tools.jar 依赖关系,只能在 java 8 之前工作
    【解决方案4】:

    试试它在 Ubuntu 和 RedHat 中的工作原理:

    java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'
    

    对于 Windows:

    java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"
    

    对于 Mac

    java -XX:+PrintFlagsFinal -version | grep -iE 'heapsize|permsize|threadstacksize'
    

    所有这些命令的输出类似于以下输出:

    uintx InitialHeapSize                          := 20655360        {product}
    uintx MaxHeapSize                              := 331350016       {product}
    uintx PermSize                                  = 21757952        {pd product}
    uintx MaxPermSize                               = 85983232        {pd product}
    intx ThreadStackSize                           = 1024            {pd product}
    java version "1.7.0_05"
    Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
    Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)
    

    要找到以 MB 为单位的大小,请将值除以 (1024*1024)。

    【讨论】:

    • 如何通过pid查找特定java进程的heap、permsize、...分隔的内存使用情况?
    • @GaryGauh 这是默认堆大小。要查找正在运行的应用程序的用法,您应该在代码中进行,或者您可以使用 jconsole。这就是我所知道的,应该还有很多其他的方式。
    • 使用jstat -gc <vmid> 运行应用程序。
    【解决方案5】:

    不使用大多数工具使用的 JMX,您所能做的就是使用

    jps -lvm
    

    并推断设置将来自命令行选项。

    默认情况下,如果没有 JMX,您将无法获取动态信息,但您可以编写自己的服务来执行此操作。

    顺便说一句:我更喜欢使用 VisualVM 而不是 JConsole。

    【讨论】:

      【解决方案6】:

      有一个可视化的命令行工具 - jvm-mon。它是一个用于命令行的 JVM 监控工具,显示:

      • 堆使用量、大小和最大值
      • jvm 进程
      • cpu 和 GC 使用率
      • 顶级线程

      当工具打开时,指标和图表会更新。

      示例:

      【讨论】:

      • 请注意 jvm-mon 仅适用于 Java8
      • ^ 有一个新版本现在也支持 Java 11。
      【解决方案7】:

      Java8 及以上版本,您可以使用以下命令:

      jcmdJAVA_PROCESS_IDGC.heap_info

      您可以参考输出中的总内存、总内存和已用内存。

      Sample Command And Output: jcmd 9758 GC.heap_info
      
      PSYoungGen  total 1579520K, used 487543K [0x0000000751d80000, 0x00000007c0000000, 0x00000007c0000000)
        eden space 1354240K, 36% used [0x0000000751d80000,0x000000076f99dc40,0x00000007a4800000)
        from space 225280K, 0% used [0x00000007b2400000,0x00000007b2400000,0x00000007c0000000)
        to   space 225280K, 0% used [0x00000007a4800000,0x00000007a4800000,0x00000007b2400000)
      ParOldGen       total 3610112K, used 0K [0x0000000675800000, 0x0000000751d80000, 0x0000000751d80000)
        object space 3610112K, 0% used [0x0000000675800000,0x0000000675800000,0x0000000751d80000)
      Metaspace       used 16292K, capacity 16582K, committed 16896K, reserved 1064960K
        class space    used 1823K, capacity 1936K, committed 2048K, reserved 1048576K
      

      更多 jcmd 命令详情,请访问链接here

      【讨论】:

      • 您需要更正您的评论。 GC.heap_info 在 Java 9 及更高版本中可用。它在 Java 8 中不可用。在此处查看另一个线程:stackoverflow.com/questions/41891127/…
      • @PavelMolchanov 我可以在 jdk1.8.0_172 中使用该命令。 /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/bin/jcmd 98270 GC.heap_info。如果可以的话,请将信息添加到引用的线程中,因为我现在还没有足够的声誉来在那里添加评论。
      • 你使用 Mac 吗?你使用 Oracle JDK 吗?我不知道它如何在您的 jdk1.8.0_172 中可用,Oracle 仅在 Java 9 及更高版本中记录了此功能:docs.oracle.com/javase/9/tools/jcmd.htm。它不在 Java 8 的 Oracle JDK 文档中。您在底部提供的链接中没有提到它:docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/…
      • 还有一个问题。请检查您的示例中运行进程 98270 的 JDK 版本。 jcmd 从进程的 JVM 获取可用命令(在您的情况下为 98270)。如果进程 98270 进程使用不同的 JDK(JDK 9 或更高版本)执行,即使 JCMD 本身来自 Java 8,您也会看到 GC.heap_info 命令可用。不同进程可用的命令可能不同。要获取可用命令,请执行:jcmp help.
      • FWIW, GC.heap_info 在 OpenJDK 8 中也绝对可用。也许只有在最近的版本中?我正在使用这个:8u191-b12-2ubuntu0.18.04.1
      【解决方案8】:

      晚会,但一个非常简单的解决方案是使用 jpsstat.sh 脚本。它提供了一个简单的实时当前内存最大内存cpu使用详细信息。

      • 转到 GitHub project 并下载 jpsstat.sh 文件
      • 右击jpsstat.sh并转到permissions选项卡并使其可执行
      • 现在使用以下命令运行脚本 ./jpsstat.sh

      这是脚本的示例输出 -

      =====  ======  =======  =======  =====
       PID    Name   CurHeap  MaxHeap  %_CPU
      =====  ======  =======  =======  =====
      2777   Test3      1.26     1.26    5.8
      2582   Test1      2.52     2.52    8.3
      2562   Test2      2.52     2.52    6.4
      

      【讨论】:

      • 在 SUSE Linux 上似乎不能开箱即用(第 38 行:声明:-A:无效选项)
      • 听起来你在需要 bash >= 4 的关联数组声明中遇到错误。另外一个问题可能是由于将脚本运行为 "sh jpsstat.sh" 。如果是这样,请尝试将脚本作为“./jpsstat.sh”运行。
      • 谢谢!用于快速故障排除的简单而神奇的工具。必须有!
      • @amarjeetAnand,currHead 和 maxHeap 的默认单位是多少?有没有办法以 mb 或用户定义的单位获取这些单位?
      【解决方案9】:

      在我的情况下,我需要检查一个 docker 容器中的标志,该容器没有大多数基本实用程序(ps、pstree...)

      使用jps 我得到了正在运行的 JVM 的 PID(在我的情况下为 1),然后使用 jcmd 1 VM.flags 我从正在运行的 JVM 中得到了标志。

      这取决于您可以使用哪些命令,但这可能会对某人有所帮助。 :)

      【讨论】:

        【解决方案10】:

        任何方法都应该给你大致相同的数字。使用-X..m-X..x 为所有代分配堆总是一个好主意。然后,您可以保证并执行 ps 以查看传递了哪些参数并因此被使用。

        对于实际内存使用情况,您可以粗略地比较 VIRT(分配和共享)和 RES(实际使用)与 jstat 值的比较:

        对于 Java 8,请参阅 jstat 以了解这些值的实际含义。假设您运行一个没有 mmap 或文件处理的简单类。

        $ jstat -gccapacity 32277
         NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC
        215040.0 3433472.0  73728.0  512.0  512.0  67072.0   430080.0  6867968.0   392704.0   392704.0      0.0 1083392.0  39680.0      0.0 1048576.0   4864.0   7225     2
        
        $ jstat -gcutil 32277
          S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
          6.25   0.00   7.96  18.21  98.01  95.29   7228   30.859     2    0.173   31.032
        

        最大

             NGCMX + S0C + S1C + EC    + OGCMX   + MCMX    + CCSMX
           3433472 + 512 + 512 + 67072 + 6867968 + 1083392 + 1048576 = 12 GB
        

        (大致接近并低于 VIRT 内存)

        最大(最小,已使用):

        215040 + 512 + 512 + 67072 + 430080  + 39680    +  4864  = ~ 1GB
        

        (大致接近 RES 内存)

        “不要引用我这个”,但 VIRT 内存大致接近或超过分配的最大内存,但只要 正在使用的内存在物理内存中是空闲/可用的,JVM 不会抛出内存异常。事实上,即使在 OS 上关闭了交换,在 JVM 启动时甚至不会检查最大内存与物理内存。 here 讨论了对 Java 进程真正使用的虚拟内存的更好解释。

        【讨论】:

          【解决方案11】:

          在Java堆大小方面,在Linux中可以使用

          ps aux | grep java
          

          ps -ef | grep java
          

          并查找 -Xms、-Xmx 以找出指定的初始和最大堆大小。

          但是,如果您感兴趣的 Java 进程没有 -Xms 或 -Xmx,则意味着您的 Java 进程正在使用默认堆大小。您可以使用以下命令找出默认大小。

          java -XX:+PrintFlagsFinal -version | grep HeapSize
          

          或特定的jvm,例如,

          /path/to/jdk1.8.0_102/bin/java -XX:+PrintFlagsFinal -version | grep HeapSize
          

          并查找 InitialHeapSize 和 MaxHeapSize,以字节为单位。

          【讨论】:

            【解决方案12】:

            首先获取进程 ID,即列出的进程中的第一个数字,来自以下之一:(或仅使用 ps aux | grep java,如果您愿意的话)

            jps -lvm
            

            然后在这里使用进程ID:

            jmap -heap $MY_PID 2>/dev/null | sed -ne '/Heap Configuration/,$p';
            jmap -permstat $MY_PID
            

            【讨论】:

              【解决方案13】:

              使用top 命令是检查程序内存使用情况的最简单方法。 RES 列显示了进程占用的真实物理内存。

              就我而言,我在 java 中读取了一个 10g 的文件,并且每次遇到 outOfMemory 异常。当RES 列中的值达到-Xmx 选项中设置的值时,就会发生这种情况。然后通过使用-Xmx 选项增加内存,一切都很好。

              【讨论】:

              • top 命令显示了为 JVM 提供了多少操作系统。这些人在问我们如何查看 JVM 中的堆空间使用情况。 JVM 使用 10g 并不意味着真正的堆空间充满了 10g 数据,因为 jvm 几乎从不将内存从堆返回给操作系统,直到您终止进程。
              【解决方案14】:

              目前还没有这样的工具可以按照您要求的格式打印堆内存 唯一且唯一的打印方法是借助 Runtime Class 编写一个 java 程序

              public class TestMemory {
              
              public static void main(String [] args) {
              
                  int MB = 1024*1024;
              
                  //Getting the runtime reference from system
                  Runtime runtime = Runtime.getRuntime();
              
                  //Print used memory
                  System.out.println("Used Memory:" 
                      + (runtime.totalMemory() - runtime.freeMemory()) / MB);
              
                  //Print free memory
                  System.out.println("Free Memory:" 
                      + runtime.freeMemory() / mb);
              
                  //Print total available memory
                  System.out.println("Total Memory:" + runtime.totalMemory() / MB);
              
                  //Print Maximum available memory
                  System.out.println("Max Memory:" + runtime.maxMemory() / MB);
              }
              

              }

              参考:https://viralpatel.net/blogs/getting-jvm-heap-size-used-memory-total-memory-using-java-runtime/

              【讨论】:

                【解决方案15】:

                从顶部查找您的 webapp/java 进程的进程 ID。 使用 jmap heap 获取堆分配。我在 AWS-Ec2 上测试了这个弹性豆茎

                您可以在下面的图片中看到应用程序的 3GB 最大堆

                【讨论】:

                  【解决方案16】:

                  如果使用 jrockit,请尝试 jrcmd 命令行工具。例如:

                  $ jrcmd 5127 print_memusage
                  5127:
                  Total mapped                  1074596KB           (reserved=3728KB)
                  -              Java heap       786432KB           (reserved=0KB)
                  -              GC tables        26316KB          
                  -          Thread stacks        13452KB           (#threads=34)
                  -          Compiled code         9856KB           (used=9761KB)
                  -               Internal          840KB          
                  -                     OS        15036KB          
                  -                  Other       146632KB          
                  -        Java class data        75008KB           (malloced=74861KB #103221 in 18709 classes)
                  - Native memory tracking         1024KB           (malloced=102KB #8)
                  

                  如heap_diagnostics等更多命令,请使用“jrcmd help”列出。

                  https://blogs.oracle.com/jrockit/entry/why_is_my_jvm_process_larger_t

                  【讨论】:

                    【解决方案17】:
                    jstat -gccapacity javapid  (ex. stat -gccapacity 28745)
                    jstat -gccapacity javapid gaps frames (ex.  stat -gccapacity 28745 550 10 )
                    

                    上述命令的示例 O/P

                    NGCMN    NGCMX     NGC     S0C  
                    87040.0 1397760.0 1327616.0 107520.0 
                    
                    NGCMN   Minimum new generation capacity (KB).
                    NGCMX   Maximum new generation capacity (KB).
                    NGC Current new generation capacity (KB).
                    

                    http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html获取更多详细信息

                    【讨论】:

                      猜你喜欢
                      • 2011-01-22
                      • 2011-12-15
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-10-15
                      • 2015-06-18
                      • 2012-09-23
                      相关资源
                      最近更新 更多