【问题标题】:Find the heapsize in JRE在 JRE 中查找堆大小
【发布时间】:2014-06-19 11:00:00
【问题描述】:

我有一个 linux 系统,其中有一个 JVM,它被 3 个 java 进程使用。

/home/codesrc>java -version
          java version "1.7.0_09"
          Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
          Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode)

所以,我有 3 个使用同一个 JRE 运行的进程。 每个进程都有自己的内存定义在命令行时像

java -Xms256m -Xmx1024m -cp $CLASSPATH <class name>
java -Xms256m -Xmx512m -cp $CLASSPATH <class name>
java -Xms256m -Xmx705m -cp $CLASSPATH <class name>

linux系统的内存是4GB。我正在尝试为每个进程分别查找堆使用情况。由于系统上没有 JDK,我无法使用 jmap、jconsole 或 jstack。 我试过了

Runtime.getRuntime().totalMemory()

但这并没有给我基于流程的信息,而且上面的输出也不正确 有没有人知道如何在仅使用 JRE 时检查堆使用情况,相当于

jmap -heap <PID>

【问题讨论】:

  • 您可以使用visualvm或jconsole连接到正在运行的进程并查看它的堆大小。
  • 我尝试通过安装 JDK 来 jmap 和 jstack,但出现以下错误:正在附加到进程 ID 10431,请稍候...线程“main”中的异常 java.lang.RuntimeException:键入“在远程 VM 中的 VMStructs::localHotSpotVMStructs 中引用的 nmethodBucket*" 不存在于远程 VMStructs::localHotSpotVMTypes 表中(应该已在该 VM 的调试版本中捕获)。无法继续。

标签: java memory-management heap-memory


【解决方案1】:

当您在服务器上启动 Java VM 并使用具有JConsole 的主机进行连接时,最好的选择是enable the JMX agent

或者,您可以使用使用 JMX 检索详细信息的本地应用程序 (see other question):

List memBeans = ManagementFactory.getMemoryPoolMXBeans();           
for (Iterator i = memBeans.iterator(); i.hasNext(); ) {

    MemoryPoolMXBean mpool = (MemoryPoolMXBean)i.next();
    MemoryUsage usage = mpool.getUsage();

    String name = mpool.getName();      
    float init = usage.getInit()/1000;
    float used = usage.getUsed()/1000;
    float committed = usage.getCommitted()/1000;
    float max = usage.getMax()/1000;
    float pctUsed = (used / max)*100;
    float pctCommitted = (committed / max)*100;

}

【讨论】:

  • 这种方法的缺点是 JMX 代理和连接器也会消耗内存。如果您的应用程序当前在内存资源中很关键并且您打开它,您可以让您的应用程序抛出 OOM =\
【解决方案2】:

您正在寻找正在运行的进程的当前内存使用情况?您是否尝试过以下方法?

Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()

【讨论】:

  • 是的,我做到了,“Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()”将为您提供 JRE 级别的整体用法,我需要在单个进程级别像 jmap -heap 这样的东西
  • 有趣。我想我的印象是每个进程都在自己的 JVM 中运行,并拥有自己的堆。不是这样吗?
  • 我不这么认为,因为我所有的 java 进程都指向同一个版本的 JRE,当我写了一个小的命令行 java 程序来计算使用 [Runtime.getRuntime() 的堆时。 totalMemory() - Runtime.getRuntime().freeMemory()] ,所以我的问题又回到了我们如何查看单个 java 进程的堆使用情况的问题。让我们考虑您的印象是正确的,那么当系统中只有 JRE 可用时,我将如何找到单个 JAVA 进程的堆使用情况。
猜你喜欢
  • 2014-02-25
  • 2020-05-08
  • 2011-01-22
  • 1970-01-01
  • 2011-02-23
  • 2012-11-04
  • 2015-08-28
  • 2014-12-24
  • 1970-01-01
相关资源
最近更新 更多