【问题标题】:How to monitor the JVM usage of large memory pages in Windows 7?如何监控 Windows 7 中大内存页面的 JVM 使用情况?
【发布时间】:2014-06-18 18:35:25
【问题描述】:

我正在尝试衡量在 Windows 7 HotSpot JVM 中使用大内存页面的性能增益。为此,我需要监控 JVM 内存使用情况,以确保实际使用了大页面。不幸的是,我无法实现这一目标。下面是我所做的设置和试验的描述:

环境设置

我正在使用 64 位 Windows 7 终极版进行测试。如Java Support for Large Memory Pages 中所述,启用“锁定内存中的页面”Windows 安全策略。我还验证了通过运行 java version 命令启用了大页面功能,如下所示:

java -XX:+UseLargePages -version

我得到以下结果,表明启用了大页面功能:

java version "1.7.0_60"
Java(TM) SE Runtime Environment (build 1.7.0_60-b19)
Java HotSpot(TM) 64-Bit Server VM (build 24.60-b09, mixed mode)

我在所有试验中都使用了来自 this video 的这个示例 Java 程序来消耗 Java 堆可用的所有内存:

public class InfinteStringHashmap {
public static void main(String[] args) throws Exception{
    Map<Long, String> map = new HashMap<Long, String>();

    for(long i=1; true; i++){
        StringBuilder sb = new StringBuilder();
        for(long j=0;j<i;j++) sb.append(" ");
        map.put(i, sb.toString());

        if(i % 1000 == 0){
            System.out.print(".");
            Thread.sleep(1000);
        }
    }
  }
}

我使用以下命令运行此示例程序(例如,固定堆大小为 512m):

java -Xms512m -Xmx512m -XX:+UseLargePages InfinteStringHashmap

我还尝试了小至 12MB 和大至 10GB 的其他堆大小。请注意,我在重新启动机器后立即运行我的测试应用程序,以确保我的可用 RAM 内存没有碎片。

内存监控试验失败

为了验证是否使用了Large Memory Pages,我尝试了:

  1. RamMap tool 来自 Windows SystInternals,它有一个大页面的特定字段。无论我如何更改堆大小,它都不会显示大内存页面的使用情况。为了验证它,我尝试了 MSDN 中的 Creating a File Mapping Using Large Pages 示例来缩小可能性。它工作得非常好(它从代码中打印出 2MB 的页面大小)。 RamMap 工具不显示任何内容。
  2. 使用this post 中建议的代码打印Java 进程使用的页面大小。它始终打印 4096(Windows 上的默认页面大小)。为了验证它,我按照this video 中的描述在Linux 版本的Hotspot JVM 上尝试了Large Pages,它成功了。但是,打印页面大小不起作用(它一直打印 4096)。
  3. Vadump 显示有关特定进程的虚拟内存统计信息的工具。 “-o”选项应该显示一个进程使用的VM类型,使用的页面数量,以及每种类型占用的总大小,可以用来推断是否使用了大页面。不幸的是,当我设置 JVM UseLargePages 选项时,此命令失败并显示错误代码 24。
  4. VmMap 工具不会更新查看的内存列。
  5. TaskManager 和 Perfmon 等简单监控工具不提供有关大页面的详细信息。

编辑:我尝试了 cmets 中建议的以下工具:

  1. Java Mission Controller:不提供页面大小信息。

  2. 进程浏览器:同上

是否可以测量进程的页面大小或监控 Windows 中大内存页面的使用情况?

【问题讨论】:

  • 我也对这个感兴趣。 -server -XX:+UseLargePages -XX:+PrintFinalFlags 显示 UseLargePages:=false(为什么?),并且所有堆内存仅在私有工作集中的事实证实了这种情况。为运行 JVM 的用户启用了将页面锁定在内存中的功能,重新启动后最多可释放 12 GB RAM。

标签: java windows memory-management


【解决方案1】:

我认为你的测试方法不合适。当你想优化 TLB 时,你使用大内存页面:

A Translation-Lookaside Buffer (TLB) is a page translation cache that holds the most-recently used virtual-to-physical address translations. TLB is a scarce system resource. A TLB miss can be costly as the processor must then read from the hierarchical page table, which may require multiple memory accesses. By using bigger page size, a single TLB entry can represent larger memory range. There will be less pressure on TLB and memory-intensive applications may have better performance.

您可以使用 [JVisualVM] 来分析您的应用程序。但是在您的测试中,您会创建新对象。我不是这里的专家,但为了 mz 对 TBL 的理解,您应该将数据从内存加载到应该在缓冲区中的结构。如果不在那里,我应该加载。

理论上,测量恒定操作次数的时间的测试应该足以看到 VM 参数的影响。

【讨论】:

  • 衡量使用大内存页面 (LMP) 的性能增益是我的最终目标。目前,我正在努力确保我真正使用它们。理想情况下,当使用 LMP 时,我创建的所有对象都应该保存在非堆内存中,并且应该防止被换出。一旦我确定要使用 LMP,您建议的测试就是衡量性能增益的正确方法。
【解决方案2】:

我不确定这是否是您要查找的内容。
但是procexp(进程资源管理器)可能会有所帮助。这没什么特别的。只是一个更出色的 Windows 7 任务管理器。

此外,随着 Java JDK 的后期下载,还有一个名为 Java Mission Control 的东西。

祝你好运!

【讨论】:

  • 我试过江铃。不幸的是,它没有提供有关使用的页面大小的信息。
【解决方案3】:

LMP 似乎是特定分配的一个特征,而不是整个过程的一个特征 (http://msdn.microsoft.com/en-us/library/windows/desktop/aa366720(v=vs.85).aspx)。跟踪哪些分配使用了哪些没有使用 LMP 可能不可行。

更新:尝试将系统调用监视器附加到您的进程。您也许可以查看是否使用正确的参数调用了 VirtualAlloc。

【讨论】:

  • JVM进程比较特殊。 “JVM 不能混合使用大页面和小页面。即使您提供了适当的“大页面”选项”(Source)。您能否详细说明附加系统调用监视器?
  • 我怀疑 JVM 使用大页面作为其堆。在 Linux 上,我会使用 strace。我在 Windows 上知道的一个系统调用监视器是 procmon - 但它只记录文件、注册表和线程/进程,而不是内存。另一个选择似乎是 Windows Performance Recorder,但我从未亲自使用过。我确信存在更多工具。
猜你喜欢
  • 2013-05-17
  • 2015-05-23
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多