确定最低内存需求和CPU使用率

13

我一直在开发一个Java软件项目,将部署到各种硬件设备上(例如树莓派、安卓手机)。

在将该项目发布为产品之前,我希望通过清晰地说明用户必须具备的最低内存和CPU硬件要求来指导用户运行我们的软件产品。

我应该如何测量它们? 有哪些可用于Java的工具?

7个回答

12

你可以使用 jvisualvm 工具来帮助你,该工具的路径为 Program Files\Java\jdk1.6.0_38\bin\jvisualvm.exe

你可以使用它来确定你的CPU使用率和内存消耗。

enter image description here

你可以看到你的CPU使用率和内存使用情况。希望这个工具能对你有所帮助。


10
您可以通过以下方式获取JVM分配的总内存: Runtime.getRuntime().totalMemory(); 并且可以使用以下方式获取JVM未使用的空闲内存: Runtime.getRuntime().freeMemory(); 所以,如果想要获取正在使用的内存,您可以将空闲内存从总内存中减去。
因此,您可以像这样操作: long Total_Memory =Runtime.getRuntime().totalMemory(); long Free_Memory=Runtime.getRuntime().freeMemory(); long Memory =Total_Memory-Free_Memory;

这些函数是否声明了堆和栈分配? - user-517752
是的,它确实说明了堆分配,但我不知道它是否说明了栈分配。此外,许多软件开发人员发布最低要求的近似值(例如512MB、1GB、2GB等)。因此,您不需要那么准确。例如,如果它使用了490MB,您可以说最低要求是512MB。 - Paul
可能为了更准确,您还需要考虑垃圾回收活动。例如,您的程序可能会积累一些垃圾,这些垃圾可能尚未清理干净。因此,在检查可用内存之前强制运行GC会更好。 - Sourabh

5

我编写了一些免费使用的基准测试,使用Java编写,有适用于Raspberry Pi和Android的不同版本。在我的网站上阅读更多关于两者结果的内容,以及基准测试和源代码下载链接(免费):

http://www.roylongbottom.org.uk/Raspberry%20Pi%20Benchmarks.htm#anchor13 http://www.roylongbottom.org.uk/android%20benchmarks.htm

也许比CPU速度和内存大小更重要的是Android和Java的版本。在我的情况下,旧版JRE无法运行后来JDK生成的代码,我也读到了关于Android相同困难的报道。

我同意,虚拟机之间的内存和CPU要求会有所不同。由于实现细节的差异,使用Oracle Java VM上低内存的程序可能在Android VM上使用更多内存。在所有平台和版本上进行基准测试是确定最低要求的可靠和准确的方法。 - RudolphEst
1
虽然这理论上回答了问题,但最好在此处包含答案的基本部分,并提供参考链接。 - SuperBiasedMan

4

提前估算内存使用率相当困难,因此建议进行一些监控(在实际负载下)以获得大致数字。

关于内存 - 典型的堆使用率图类似于此问题中列出的一个,并且看起来像一个锯齿形。 在正常情况下,锯齿形的最高点是GC发生的地方。您可以降低此限制并更频繁地调用GC,从而导致较长的延迟/性能变差-因此,这取决于您是否接受这些延迟。从链接问题上的图像中,我会说最小堆大小应该为300M加上栈,通常很小而且不会波动太多,除非您做了很多字符串处理等操作。

关于CPU - 再次,这应该首先来自于认为可接受的内容,实时和后期处理是两个完全相反的情况。 Java实际上并没有添加任何特定功能。例如,Oracle为Weblogic服务器提供了简短的估算指南,但这可能与您的情况无关。在sister SO网站上也有类似的讨论。最好进行一些测试并确定不可接受的点。


4
你可以使用像JProfiler、JProbe等性能分析工具来在负载下分析应用程序的CPU和内存使用情况。
当你拥有长时间运行测试的CPU和内存使用结果时,比如几天的测试,你可以确定Java应用程序的最小和最大需求。

3
以下是代码示例(另请参见此答案):
package client;

import java.io.File;

import java.text.NumberFormat;

public class SystemInfoUtil
{


  private Runtime runtime = Runtime.getRuntime();

  public String findInfo()
  {
    StringBuilder sb = new StringBuilder();
    sb.append(this.getOsInfo());
    sb.append(this.getMemInfo());
    sb.append(this.getDiskInfo());
    return sb.toString();
  }

  public String getOSname()
  {
    return System.getProperty("os.name");
  }

  public String getOSversion()
  {
    return System.getProperty("os.version");
  }

  public String getOsArch()
  {
    return System.getProperty("os.arch");
  }

  public long getTotalMem()
  {
    return Runtime.getRuntime().totalMemory();
  }

  public long getUsedMem()
  {
    return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
  }

  public String getMemInfo()
  {
    NumberFormat format = NumberFormat.getInstance();
    StringBuilder sb = new StringBuilder();
    long maxMemory = runtime.maxMemory();
    long allocatedMemory = runtime.totalMemory();
    long freeMemory = runtime.freeMemory();
    sb.append("Free memory: ");
    sb.append(format.format(freeMemory / 1024));
    sb.append("<br/>");
    sb.append("Allocated memory: ");
    sb.append(format.format(allocatedMemory / 1024));
    sb.append("<br/>");
    sb.append("Max memory: ");
    sb.append(format.format(maxMemory / 1024));
    sb.append("<br/>");
    sb.append("Total free memory: ");
    sb.append(format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024));
    sb.append("<br/>");
    return sb.toString();

  }

  public String getOsInfo()
  {
    StringBuilder sb = new StringBuilder();
    sb.append("OS: ");
    sb.append(this.getOSname());
    sb.append("<br/>");
    sb.append("Version: ");
    sb.append(this.getOSversion());
    sb.append("<br/>");
    sb.append(": ");
    sb.append(this.getOsArch());
    sb.append("<br/>");
    sb.append("Available processors (cores): ");
    sb.append(runtime.availableProcessors());
    sb.append("<br/>");
    return sb.toString();
  }

  public String getDiskInfo()
  {
    /* Get a list of all filesystem roots on this system */
    File[] roots = File.listRoots();
    StringBuilder sb = new StringBuilder();

    /* For each filesystem root, print some info */
    for (File root: roots)
    {
      sb.append("File system root: ");
      sb.append(root.getAbsolutePath());
      sb.append("<br/>");
      sb.append("Total space (bytes): ");
      sb.append(root.getTotalSpace());
      sb.append("<br/>");
      sb.append("Free space (bytes): ");
      sb.append(root.getFreeSpace());
      sb.append("<br/>");
      sb.append("Usable space (bytes): ");
      sb.append(root.getUsableSpace());
      sb.append("<br/>");
    }
    return sb.toString();
  }
}

0

以下列出了一些用于监控和分析Java应用程序的选项。

  1. Jconsole
  2. JVisualVM
  3. NewRelic插件
  4. Yourkit Profiler

但是,对于负载测试,您可以使用像Jmeter这样的应用程序来测试应用程序在使用情况下,并且还可以进行压力测试以确定应用程序构建的基准。

不要忘记对前端和后端服务器进行端到端分析。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接