【问题标题】:How to start a java process from C++, and get the memory it uses?如何从 C++ 启动 java 进程,并获取它使用的内存?
【发布时间】:2012-02-10 08:30:12
【问题描述】:

我无法让 GC 始终如一地工作,以便测量某个类的实例使用的内存量。 GC 是不可预测的(花了 2 天时间在谷歌上搜索它,所以如果您提供参考,请确保您尝试过,它有效,否则我很可能已经知道您的解决方案)

我使用的是 Java EE 5,因此我无法使用 JVisuamVM。

所以我考虑使用 JNI,从 C++ 代码开始我的进程,并获取它们使用的内存量,因为我听说 C++ 可以做到这一点。

我已经将 JNI 用于“hello world”之类的东西,所以我不需要一步一步的介绍,我只需要知道我如何从 C++ 启动另一个进程 (类似于 Runtime.getRuntime().exec("java MyClassWithMainMethod");),以及我如何获取该进程使用的内存。

【问题讨论】:

  • 没有标准的方法来做到这一点,你正在使用什么操作系统?
  • 我不明白你原来的问题。您想测量一个特定类使用的内存量,您可以通过从使用的总内存中计算该量来做到这一点,对吗?您是否考虑过使用 MXBeans,如果是,有什么问题? “GC 不可预测”是什么意思?收集的时机或结果?你试过不同的 GC 吗?
  • C++ 可以为 C++ 中的内存做到这一点。 JVM 在启动时分配最大堆大小,因此它看起来一直是 100%。我建议您使用适用于您的系统的内存分析器。
  • 我不同意。 Windows 中的 processmonitor 显示当前内存消耗,而不是当前分配的内存。因此有可能从外部监控内存消耗。

标签: java c++ memory process java-native-interface


【解决方案1】:

如果您遇到内存泄漏,请尝试使用 JProfiler 或任何其他 Java 分析器。

在 Windows 中创建进程:

STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;
if (CreateProcess(path, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &info, 
    &processInfo))
{
    PROCESS_MEMORY_COUNTERS pmc;
    if ( GetProcessMemoryInfo( processInfo.hProcess, &pmc, sizeof(pmc)) )
    {
        printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
        printf( "\tPeakWorkingSetSize: 0x%08X\n", 
              pmc.PeakWorkingSetSize );
        printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
        printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n", 
              pmc.QuotaPeakPagedPoolUsage );
        printf( "\tQuotaPagedPoolUsage: 0x%08X\n", 
              pmc.QuotaPagedPoolUsage );
        printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n", 
              pmc.QuotaPeakNonPagedPoolUsage );
        printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n", 
              pmc.QuotaNonPagedPoolUsage );
        printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage ); 
        printf( "\tPeakPagefileUsage: 0x%08X\n", 
              pmc.PeakPagefileUsage );
    }
    ::WaitForSingleObject(processInfo.hProcess, INFINITE);
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
}

链接:
http://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms683219.aspx

【讨论】:

    【解决方案2】:

    没有独立于平台的方法,但是您可以像启动任何命令行进程一样启动 java 进程。在 UNIX 上,这可能意味着 fork() 和 exec(),对于第一次调用,您将执行 if(( pid = fork() )) 为您提供新进程的进程 id(然后执行)。 (请注意,else() 表示您处于当前进程中)。

    一旦你执行并启动了进程,你就会知道它的进程id(它是由fork()返回的)

    您可以使用系统工具检查其内存使用情况,如下所示: How to measure actual memory usage of an application or process?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多