【问题标题】:JVM is using too much memory in serverJVM 在服务器中使用了太多内存
【发布时间】:2014-01-24 06:56:34
【问题描述】:

我有一个 Web 应用程序,它记录来自各种门户的数据。 这是一个使用 mongo db 作为数据库服务器的 java 应用程序。 我的应用程序足够快,但我面临的问题是 Tomcat 在每个应用程序服务器上消耗了太多的 Ram 内存。我必须每两个小时重新启动一次 tomcat 以释放此内存,否则它会变得无响应。我运行 netstat -n | wc -l 在每台服务器上,平均输出在每台服务器上为 1000。 我在我的 servlet 和 mongo dao 中引入了 System.gc 来强制 GC 释放内存,但它会将 CPU 使用率增加到 100%。 您能否建议如何解决此内存问题。

【问题讨论】:

  • 在特定时间创建转储并对其进行分析。
  • 我以 30 分钟的间隔创建了堆转储,但某些对象始终没有明确的模式以递增的顺序排列。我发现创建了很多字符串对象。
  • 您是否看到内存使用接近满并且 GC 启动的证据?与此同时,“netstat -n | wc -l”返回 1000 听起来很多。在我的机器上,我得到了 100 左右。会不会是连接没有正确关闭?
  • 这 1000 个已建立连接,正在等待。我也检查了我的数据库连接,在我的代码中我正确地关闭了它(我想是这样)我总是用 db.requestStart() 开始我的数据库连接,最后我调用 db.requestDone()。

标签: java tomcat garbage-collection


【解决方案1】:

我使用以下方法来查找 Java 中的内存泄漏。我使用 jProfiler 取得了巨大成功,但我相信任何具有绘图功能的专用工具(差异更容易以图形形式分析)都可以工作。

启动应用程序并等待它进入“稳定”状态,此时所有初始化完成并且应用程序处于空闲状态。 多次运行怀疑产生内存泄漏的操作,以允许任何缓存、与数据库相关的初始化发生。 运行 GC 并拍摄内存快照。 再次运行该操作。根据操作的复杂性和处理的数据的大小,操作可能需要运行几次到多次。 运行 GC 并拍摄内存快照。 对 2 个快照运行 diff 并对其进行分析。 基本上分析应该从对象类型的最大正差异开始,并找出导致这些额外对象滞留在内存中的原因。

对于在多个线程中处理请求的 Web 应用程序,分析变得更加复杂,但通用方法仍然适用。

我做了很多专门针对减少应用程序的内存占用的项目,这种带有一些特定于应用程序的调整和技巧的通用方法总是很有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-02
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多