通过 Java 应用程序监视自己的内存使用情况

2022-09-03 12:55:21

我想在一个Java进程中运行几个REST Web应用程序,以节省内存并在Akka的帮助下轻松扩展。我想估计每个请求处理程序消耗多少内存,并检测这些对整个系统的危险。

  1. 是否可以在该进程中几乎实时地监视内存使用情况,并找出每个请求处理程序使用了多少内存?我需要什么来实现这一目标?有什么工具吗?

  2. 是否有可能捕获并根据内存使用情况执行某些操作,例如仅崩溃超过假定内存限制的请求处理程序?如果是这样,那会有什么不好的呢?out of memory exception


答案 1

程序的总使用/可用内存可以通过java.lang.Runtime.getRuntime()在程序中获得;

运行时有几个与内存相关的方法。以下编码示例演示了其用法。

package test;

import java.util.ArrayList;
import java.util.List;

public class PerformanceTest {
  private static final long MEGABYTE = 1024L * 1024L;

  public static long bytesToMegabytes(long bytes) {
    return bytes / MEGABYTE;
  }

  public static void main(String[] args) {
    // I assume you will know how to create a object Person yourself...
    List<Person> list = new ArrayList<Person>();
    for (int i = 0; i <= 100000; i++) {
      list.add(new Person("Jim", "Knopf"));
    }
    // Get the Java runtime
    Runtime runtime = Runtime.getRuntime();
    // Run the garbage collector
    runtime.gc();
    // Calculate the used memory
    long memory = runtime.totalMemory() - runtime.freeMemory();
    System.out.println("Used memory is bytes: " + memory);
    System.out.println("Used memory is megabytes: "
        + bytesToMegabytes(memory));
  }
} 

答案 2

为了回答您的第一个问题,您可以使用许多工具来监视内存使用情况,但是我不知道有任何应用程序可以“实时”将内存使用情况映射到线程。在应用程序中,您可以使用 MemoryMXBeanMemoryPoolMXBeans 来监视内存使用情况,

回答你的第二个问题:不,不是真的。除了捕获OOME通常是一个坏主意之外,主要问题是接收异常的线程可能不是实际的罪魁祸首。OOME 被抛出在发出最终分配请求的线程上。但是,其他一些线程可能是填充大部分内存的线程。另一个问题是,由于 OOME 可以随时被抛出,因此它可能被抛出到应用程序中的一些关键代码中,使其处于瘫痪状态。长话短说,当您收到OOME时,您几乎总是希望重新启动应用程序。