我希望在一个Java进程中运行多个REST Web应用程序,以便在Akka的帮助下轻松保存内存和扩展。我想估计每个请求处理程序消耗多少内存并检测整个系统的这些内存。
是否有可能在该进程内几乎实时监视内存使用情况,并了解每个请求处理程序使用了多少内存?我需要实现的目标是什么?有没有工具?
是否可以捕获out of memory exception
并根据内存使用情况做一些事情,例如仅崩溃请求处理程序超出假定的内存限制?如果是这样,那可能会有什么不妥?
答案 0 :(得分:10)
程序的总使用/可用内存可以通过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));
}
}
答案 1 :(得分:5)
要回答您的第一个问题,您可以使用许多工具来监控内存使用情况,但我不知道在“实际”时间内将内存使用情况映射到线程的任何应用程序。在应用程序中,您可以使用MemoryMXBean和MemoryPoolMXBeans来监控内存使用情况,
回答你的第二个问题:不,不是真的。除了捕获OOME通常是一个坏主意之外,主要问题是接收异常的线程可能不是真正的罪魁祸首。 OOME被抛出到进行最终分配请求的线程上。但是,一些其他线程可能是填满大部分内存的线程。另一个问题是,由于OOME可能随时被抛出,因此可能会将其抛入应用程序中的某些关键代码中,使其处于残缺状态。长话短说,你几乎总是想要在收到OOME时重启你的应用程序。
答案 2 :(得分:4)
监视应用程序的一个简单易用的工具是VisualVM。您可以尝试一下:http://visualvm.java.net/
答案 3 :(得分:2)
您还可以添加代码语句来监控可用内存,如:
Runtime runtime = Runtime.getRuntime();
System.out.println("Free memory: " + runtime.freeMemory() + " bytes.");
无法处理此异常。问题是,如果您在公共应用服务器(例如tomcat)中运行所有Web服务,那么如果存在“内存不足”异常,JVM将会关闭。尝试查看程序中是否存在任何内存泄漏或内存处理错误。您可以在Netbeans或Eclipse中使用分析。此外,使用“findbugs”或“sonar”等工具进行代码分析可能会向您显示代码中可能存在的不良做法。
在任何情况下,使用有关垃圾收集或JVM内存的Java选项(如-Xmx)可以减少此类异常并提高性能。