【问题标题】:How to observe programatically how much memory a program used?如何以编程方式观察程序使用了多少内存?
【发布时间】:2015-12-04 14:34:32
【问题描述】:

我正在JAVA 开发一个编程竞赛管理器。

竞赛管理器的概念:

竞赛管理器的主要概念总结如下。如果你有想法,你可以跳过图片前的行。

  • 服务器在 Judge PC 上运行。
  • 所有参赛者都作为客户与裁判建立联系。
  • 为参赛者提供问题陈述的硬拷贝,他们在C++ 上写下解决方案。他们使用用 JAVA 编写的 Contest Manger 软件提交解决方案。
  • 对于每个问题,Judge 在文件中都有一些输入数据和在文件中对应的输出数据。
  • 当参赛者提交他的解决方案时,裁判服务器会根据裁判提供的输入运行它。
  • 然后,裁判服务器将参赛者的输出与之前提供的正确输出进行匹配。
  • 然后Judge server根据Accepted、Wrong Answer、Compile Error、Time Limit Exceeded等匹配结果进行判断。
  • 每个问题都有一个预定义的时间限制。这意味着提交的解决方案必须在特定时间段内运行。 (通常在 1 秒到 15 秒之间)
  • 所有参赛者都可以看到提交的解决方案的结果。下面的图片将清除场景。这是提交队列,所有参赛者和评委都可以看到。

问题背景:

在图片中,您可以看到一个红色标记区域,其中每个提交的解决方案经过的时间都以毫秒为单位。我可以通过以下代码轻松完成:

long start,end;
start = new Date().getTime();
int verdictCode = RunProgram(fileEXE, problem.inputFile, fileSTDOUT, problem.timeLimit);
end = new Date().getTime();
submission.timeElapsed = end - start;

在这里,RunProgram 函数运行提交的解决方案(程序)并针对输入文件生成输出文件。如果您需要它的详细信息,请稍后问我,我会描述。

主要问题:

但是,还有另一种类型的判定,称为Memory Limit Exceeded 这里没有实现。我想实现它。但是不知道该怎么做。我用谷歌搜索了它。有人讲述了剖析,但我不知道如何正确地做到这一点,也不知道它是否能达到我的目的。

这意味着会有一个名为Memory Elapsed 的列,例如Time Elapsed。 这样做是可能的,因为像Codeforces 这样的在线评委已经在展示它。但我的问题是,是否可以在JAVA 中做同样的事情?

  • 如果是,那么如何?
  • 如果不是,那你怎么确定?

注意:

  • 该软件有一些依赖性。它必须在 Windows 平台上运行。

【问题讨论】:

    标签: java memory-management heap-memory


    【解决方案1】:

    我想您是在问关于用 C++ 编写的本机程序的统计数据,对吗? Java 无法测量操作系统中其他程序的内存使用情况,只能获取 Java 中当前 JVM 的内存信息。要测量内存使用情况或其他进程的 CPU 使用情况,您需要依赖于平台的解决方案(使用 JNI 运行的本机代码)。幸运的是,人们已经实现了类似的东西,因此您可以使用普通的 Java 对象来做您想做的事情,而无需编写任何 C/JNI 代码。查看Hyperic Sigar 库,以轻松完成您想做的事情。

    【讨论】:

    【解决方案2】:

    我想你想要Runtime class

    Runtime runtime = Runtime.getRuntime(); 
    System.out.println("Free memory: " + runtime.getFreeMemory() + " / " + rutime.getMaxMemory());
    

    【讨论】:

    • 我该如何实现它?我怎样才能知道特定程序消耗了多少内存?
    • 您想查看从 java 服务器生成的 C++ 进程是否曾经超出内存?部分取决于 RunProgram 如何运行 C++ 程序,以及 Java / C++ 端是否有任何 API。 .可编写脚本的探查器将起作用。另一种“半万无一失”的方式是使用唯一键执行每个进程,并有一个线程来扫描/解析顶部并在超出时抛出错误。
    • 在我的例子中,rt = Runtime.getRuntime(); pr = rt.exec(command); 其中command 是从命令行运行 C++ 程序所需的字符串。
    • 正确的做法是@mvd 下面提到的(Hyperic)。穷人的方法是运行一个线程来查询 top(如果在 *nix 上)系统并解析它。我认为以正确的方式做事会少一些工作。
    • 那么,我怎样才能在短时间内抓住/掩盖正确方法的想法呢? @NathanDunn
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    相关资源
    最近更新 更多