简体   繁体   中英

Determining minimum memory requirement and CPU usage

I have been working on one Java software project, which will be deployed to various hardware devices (eg, raspberry pi, android phone).

Before releasing this project as product, I would like to guide users by clearly stating the minimum requirements (in terms of memory and CPU) or hardware device the user must have in order to run our software product.

How can I measure them? What are tools available for Java?

You may take help of jvisualvm path of this tool is Program Files\\Java\\jdk1.6.0_38\\bin\\jvisualvm.exe

You may use it to determine your cpu utilization and memory consumption.

在此输入图像描述

As you can see your CPU utilization and memory utilization. Hope this tool may help you.

You can get the Total memory allotted to the JVM with:

Runtime.getRuntime().totalMemory();

and the Free memory(the unused memory allotted to the JVM) with:

Runtime.getRuntime().freeMemory();

So, to get the memory in use, you can subtract the free memory from the total memory.

So, you could do something like this:

long Total_Memory =Runtime.getRuntime().totalMemory(); long Free_Memory=Runtime.getRuntime().freeMemory(); long Memory =Total_Memory-Free_Memory;

Some of my free to use benchmarks are written in Java, with variations that run on Raspberry Pi and Android. Read more on my site for results of both, plus benchmark and source code download links (free):

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

Perhaps more important than CPU speed and memory size are versions of Android and Java. In my case, older versions of JRE would not run code produced by later JDK and I have read about the same difficulties with Android.

It is rather hard to estimate the memory usage in advance, and therefore I suggest to do some monitoring (under real load) to get the ballpark numbers.

With regards to memory - typical heap usage graph is similar to one listed in this question and looks like similar to a saw. Under normal circumstances the top point of the saw is where the GC happens. You could lower this limit and invoke GC more frequently, resulting longer delays/worse performance - so it's up to you if these delays are acceptable. From the image on linked question I'd say the minimal heap size should be 300M plus stack which is most often insignificant and does not fluctuate that much, unless you do lots of String churning, etc.

With regards to CPU - again, this should come first from what you find acceptable, real time and some post-processing being two opposite corner cases. Java doesn't really add any specifics to this. Oracle, for example, has a short estimation guide for Weblogic server , but this might be irrelevant to your case. There's also a similar discussion on a sister SO site. The best is to do some testing and determine the point at which things become unacceptable.

You can use profiling tools like JProfiler, JProbe etc. to profile the CPU and memory usage of your application under load.

When you have the results of CPU and memory usage of long running test, say a test of few days, you can be sure with the minimum and also maximum requirements of your java application.

How about following code (Also see answer here )

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();
  }
}

There are some options available for monitoring & analyzing Java application as listed below.

  1. Jconsole
  2. JVisualVM
  3. NewRelic Plugin
  4. Yourkit Profiler

However for load testing you can use application like Jmeter for testing application on use cases and can also do stress testing to determine benchmark of application build.

Do not miss to analyze your frontend and backend servers too for end-to-end analysis.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM