【问题标题】:how to make war file take up less memory如何使war文件占用更少的内存
【发布时间】:2012-08-28 15:31:38
【问题描述】:

我需要有关如何减少我的网络应用程序的内存使用量的帮助。这样我就可以更适合我的网络服务器了。

所以我正在构建一个带有 JSF 2.0 的 Java Web 应用程序,该应用程序在 Eclipse helios 中开发并在 Apache tomcat 服务器上运行。我还有一个带有 tomcat 的专用虚拟服务器,我在其中部署这些战争文件。 webApp 的大小约为 35MB(它有很多 jar 等)但是当我将它部署到我的 tomcat 网络服务器时,我可以看到它需要大约 300MB 的 RAM,这正常吗?我的专用服务器只有 2GB 的内存,通常有 1 个可以使用。所以我一部署 3 个应用程序就会收到 OOM 错误,我已经收到 permgen OOM 和 out of swamp Memory 错误;为了解决这个问题,我将我的 MaxPermGen 提高到大约一个 gig 并重新启动服务器以取回一些沼泽空间。所以我尝试部署较小的旧应用程序(大约 15MB),它们占用的内存要少得多。如果我有 1 GB 的内存,我希望能够将更多应用程序放入我的网络服务器中,而不会出现任何 OOM 错误。

现在我找到了this stack overflow Question,这可以应用于我的情况吗?如果是这样,tomcat服务器中的常用文件夹是什么?以前有人这样做过,还是有其他更有效、不那么复杂的方法?

任何想法和/或评论都非常感谢。谢谢!

我的

【问题讨论】:

  • 您是否使用任何 JVM 参数来调整堆大小?除非您对静态数据、字符串文字和类元数据的使用率很高,否则您不需要 1gb 的 maxpermgen。
  • 这些是我使用的JVM参数 -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled -XX:PermSize=256m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError
  • 尝试用 -Xmx1024m 替换 -XX:MaxPermSize=1024m

标签: java jakarta-ee tomcat7 out-of-memory war


【解决方案1】:

我部署这些战争文件。 webApp 的大小约为 35MB(它有很多 jars 等)

只有您使用的文件才会占用任何内存。删除不使用的类会节省磁盘空间,但不会节省内存。

但是当我将它部署到我的 tomcat 网络服务器时,我可以看到它需要大约 300MB 的 RAM,这正常吗?

如果您的服务器中有 300 Mb 可用空间,它将全部使用。如果您有 3 GB 的可用空间,它也可能会使用所有这些空间。在实际使用服务器并执行一次 Full GC 后,您需要查看使用了多少。

如果我有 1 GB 的内存,我希望能够将更多应用程序放入我的网络服务器,而不会出现任何 OOM 错误。

您需要确定每个应用程序真正需要多少内存。或者您需要购买更多内存,因为 1 GB 的成本约为 20 美元。 (我假设它是一个托管解决方案,其中内存成本要高得多;)

【讨论】:

  • 是的,这是一个虚拟解决方案,所以我必须为更多的 ram 支付更多费用,这很好。我只是想知道是不是这样。我将按照 dcernahoschi 的建议来查找应用程序的内存占用。但就像你说的,如果我有 300MB 的空闲空间或 3GB,我怎么能告诉它只使用“xX”数量(即如果足迹只有 300MB 的内存)我怎么告诉它只使用 300MB 的内存?
  • 您可以减小最大堆大小,直到它停止工作。如果不对每个应用程序使用 JVM,就无法限制单个应用程序。这会减慢应用程序的速度,但您会知道它将运行的最小内存。
【解决方案2】:

war 文件的大小并不能决定应用程序消耗多少内存。此外,如果您设法在您的 tomcat 中启动 5 个应用程序,这并不意味着它们仍然会在 3 周后运行。

为此,您需要分别对每个应用程序进行负载测试以确定它的内存占用量(从长远来看它需要多少内存)。

为此,您需要:

  • 估计将使用您的应用程序的最大并发用户数
  • 为每个用户分配一个测试用例。例如:您可能有最多 100 个并发用户,其中 10 个注册、10 个搜索一些东西、10 个输入一些数据等。
  • 使用JMeterGrinder 之类的工具为每个用例编写/记录测试
  • 在负载测试期间使用 java 内存分析器监控内存使用情况、垃圾回收等

在运行负载生成器一段时间后,使用的内存应该稳定在某个地方:1GB、1.5GB 等。这就是您的内存占用量。您需要确保您的硬件提供这么多内存。

如果没有稳定,那么你有内存泄漏,你最终会得到一个OutOfMemoryError。但这是另一个话题。

您将尝试各种 jvm 内存配置并注意应用程序的性能:TPS 数。由以上工具提供。

我刚刚触及了冰山一角,负载和性能测试是一个密集的话题。

【讨论】:

    【解决方案3】:

    正常的内存使用取决于 webapp 及其所做的事情。正如@Peter Lawrey 所说,WAR 文件的大小和使用的内存量之间没有直接关系。

    是的,将通用 JAR 文件从 WAR 中移出并移入共享库文件夹的方法会减少内存,尽管总体上可能不会产生显着差异。有关库文件夹名称,请参见 Tomcat7 documentation

    共享库中的类只会为 JVM 加载一次,而不是为每个使用它的 webapp 加载一次。但是,如果任何类具有静态状态,您会发现该状态现在在所有 Web 应用程序之间共享。这可能会导致一个 webapp 中的对象/类型被另一个 webapp 看到,这可能会导致问题。

    如果我有 1 GB 的内存,我希望能够将更多应用程序放入我的网络服务器,而不会出现任何 OOM 错误。

    好吧,Java 确实往往会占用大量内存,实际上,在给定的内存量(和努力)下,您可以做的事情是有限度的。归根结底,我怀疑您将需要向下修改您的期望……或者购买具有更多内存的虚拟机。


    在走这条路之前,我建议您使用 Java 内存分析器来查看您的 web 应用程序的设计和实现是否存在导致它们使用大量内存的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-25
      • 2018-06-12
      • 1970-01-01
      • 2016-03-27
      • 2014-04-07
      • 2012-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多