Java 为什么我的 tomcat 应用程序的内存使用量不断增长?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/565871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:18:35  来源:igfitidea点击:

Why does my tomcat application's memory usage keep growing?

javatomcatmemory-managementmemory-leaks

提问by user68461

My application is running on Windows Server 2000. The memory usage keeps growing (from 145m).

我的应用程序在 Windows Server 2000 上运行。内存使用量不断增长(从 145m)。

Is that normal? I am new to Java. The version is Tomcat5.5.

这是正常的吗?我是 Java 新手。版本为Tomcat5.5。

回答by GEOCHET

This is not normal, and is probably indicative of a memory leak.

这是不正常的,可能表示内存泄漏

You should try using a memory profilerto see where your application is leaking.

您应该尝试使用内存分析器来查看您的应用程序泄漏的位置。

In general, you should be looking for loops or repeated operations where objects are created but not disposed ofcorrectly.

通常,您应该寻找创建但未正确处理对象的循环或重复操作。

回答by neesh

You may have a memory leak. I would first connect jconsole to your application to determine if it is permgen space or just heap memory and then proceed to figure out where the leak is. Can you give us some more information? What is going on in your application as the memory grows?

您可能有内存泄漏。我会首先将 jconsole 连接到您的应用程序以确定它是永久空间还是堆内存,然后继续找出泄漏的位置。你能给我们更多的信息吗?随着内存的增长,您的应用程序发生了什么?

If you are relatively new to diagnosing this kind of problem, I would recommend jprofiler. You can download a fully functional trial version and take memory snapshots to see what objects are in memory. You can use this information to figure out which objects are the source of the leak.

如果您对诊断此类问题比较陌生,我会推荐 jprofiler。您可以下载功能齐全的试用版并拍摄内存快照以查看内存中的对象。您可以使用此信息来确定哪些对象是泄漏源。

回答by Alex Miller

If it only ever grows, then that's a memory leak. But if it grows up to your max heap, then drops, then that is normal garbage collection behavior. There are many tools you can use to learn more. One of the simplest is to connect with JConsole (part of the JDK) and observe your heap over time.

如果它只会增长,那就是内存泄漏。但是如果它增长到您的最大堆,然后下降,那么这是正常的垃圾收集行为。您可以使用许多工具来了解更多信息。最简单的方法之一是连接 JConsole(JDK 的一部分)并随时间观察您的堆。

You can also look at garbage collection information with various switches and parameters like -verbose:gc to start with.

您还可以使用各种开关和参数(如 -verbose:gc 开始)查看垃圾收集信息。

If you want to diagnose memory leaks, there are a number of excellent tools available, including several free ones that work with Eclipse, NetBeans, IntelliJ, etc.

如果您想诊断内存泄漏,可以使用许多出色的工具,包括几个可与 Eclipse、NetBeans、IntelliJ 等一起使用的免费工具。

回答by Tom Hawtin - tackline

The default behaviour of Sun "server" HotSpot is to enlarge the heap rather than clearing SoftReferences (used for caches). The default was to keep them for one second for every megabyte of maximum heap size available. So, expect the heap to grow to the maximum size. If you do actually run out of memory with OutOfMemoryExceptionor performance becomes poor (due to excessive GC or small caches), then you need to look for memory leaks.

Sun“服务器”HotSpot 的默认行为是扩大堆而不是清除SoftReferences(用于缓存)。默认情况下,对于每兆字节的最大可用堆大小,将它们保留一秒钟。因此,预计堆会增长到最大大小。如果您确实用完内存OutOfMemoryException或性能变差(由于过多的 GC 或小缓存),那么您需要查找内存泄漏。

Also Tomcat servers often suffer from memory leaks after reloading applications. For instance, Tomcat shares threads between all applications, which often causes Sun's ThreadLocalimplementation to improperly retain values.

此外,Tomcat 服务器在重新加载应用程序后经常会出现内存泄漏。例如,Tomcat 在所有应用程序之间共享线程,这通常会导致 Sun 的ThreadLocal实现不正确地保留值。

回答by Sarel Botha

IMO Tom Hawtin's answer is the best. It grows until it hits the max, then runs GC. In a server environment this makes sense: You want the best performance, not best memory usage. You pre-calculate the total amount of memory, then give each app a maximum and then everything fits and has the best performance. This behavior can be tweaked.

IMO Tom Hawtin 的回答是最好的。它一直增长直到达到最大值,然后运行 ​​GC。在服务器环境中,这是有道理的:您想要最佳性能,而不是最佳内存使用。您预先计算内存总量,然后给每个应用程序一个最大值,然后一切都适合并具有最佳性能。可以调整此行为。

Use jconsole to look at how much is really being used. Do GC and watch what it goes down to. That number should not grow over time or you have a memory leak. Use visualvm to debug a memory leak.

使用 jconsole 查看实际使用了多少。执行 GC 并观察结果。该数字不应随着时间的推移而增长,否则您会出现内存泄漏。使用 visualvm 调试内存泄漏。

Each time you reload an application it uses additional Perm Gen memory which cannot be reclaimed (in Sun JVM, others like JRockit don't have this problem). In production you shouldn't be reloading the app. Restart Tomcat each time. If you really want to keep doing it then you can increase the max memory and also increase the Max Perm Gen memory with the flag -XX:MaxPermSize=256m

每次重新加载应用程序时,它都会使用无法回收的额外 Perm Gen 内存(在 Sun JVM 中,JRockit 等其他应用程序没有此问题)。在生产中,您不应该重新加载应用程序。每次都重启Tomcat。如果您真的想继续这样做,那么您可以增加最大内存并使用标志 -XX:MaxPermSize=256m 增加 Max Perm Gen 内存

回答by Edwin

With the program Lambda Probeyou can easily look at the memory usage in Tomcat. (option System information - Memory utilization). You can see in a graph Survivor Space Perm Gen Tenured Gen Eden Space Code Cache

使用Lambda Probe程序,您可以轻松查看 Tomcat 中的内存使用情况。(选项系统信息 - 内存利用率)。您可以在图中看到 Survivor Space Perm Gen Tenured Gen Eden Space Code Cache

Just deploy this warfile to tomcat and set the startup option -Dcom.sun.management.jmxremote to the Java startup.

只需将此 warfile 部署到 tomcat 并将启动选项 -Dcom.sun.management.jmxremote 设置为 Java 启动。

Now you can see what part of the memory grows.

现在您可以看到内存增长的部分。