【问题标题】:Tomcat library eager loading of jarsTomcat 库急切加载 jars
【发布时间】:2014-08-11 22:56:24
【问题描述】:

我在 Tomcat server (v7) 上部署了两个应用程序,这两个应用程序都使用相同的共享库。我想减少这些应用程序在 JVM 上的 permgen 内存占用,因此我决定将公共共享库从单独的战争中取出,并将其放在 tomcat library folder 中。

但是这个实验适得其反,因为 ClassLoader 是每个应用程序上下文,即使我将库移动到 tomcat lib,共享库被加载到两个应用程序的上下文中,更糟糕的是它被加载到其他应用程序的上下文中不使用此共享库的应用。

有没有办法在 web 服务器的上下文中只加载一次库?

我了解线程安全的风险,这些风险在我的案例中得到了缓解。

【问题讨论】:

  • 恐怕没有。对不起。
  • 您的共享库是否太大以至于内存消耗成为问题?
  • @dimoniy 是的,大约 30 MB,我以 2 个应用为例,但我们正在成长,并且正在添加新应用并使用相同的共享库。
  • @Puru-- 也许你应该将你的库提取到 Web 服务中,然后在本地部署和使用它。呼叫和开发成本将产生开销。另一种选择是 RCP。

标签: java tomcat web-applications classloader


【解决方案1】:

来自 Tomcat lib 目录中 jar 的类有自己的类加载器,在所有部署的应用程序之间共享。

正如您所注意到的,每个单独的应用程序也有自己的类加载器。

此时,了解 Tomcat 为每个应用程序查找类的位置非常重要。套用Apache Tomcat Class Loader HOW-TO,应用程序类按以下顺序排列:

  1. JVM 引导类
  2. 系统类
  3. /WEB-INF/应用程序的类
  4. /WEB-INF/lib/*.jar 类
  5. 通用类加载器(“Tomcat lib”目录中的 jars)

上面的 1,2 和 5 项是独立的类加载器,它们有自己的存储库。第 3 项和第 4 项是单个类加载器,但每个 Web 应用程序都有一个单独的类加载器。

因此,如果您已将库 jar 复制到 Tomcat lib 目录中,并且没有从您的网络应用程序中删除它,那么您仍将在您的网络应用程序中加载和使用该 jar。仔细检查部署以确保库 jar 实际上不再存在于每个应用程序的 WEB-INF/lib 目录中。

【讨论】:

  • 你说得对,我在阅读 Apache 文档后发现了同样的情况。我确信我从战争文件中删除了 jar。我不明白的是内存使用量增加。当这个共享库在 WAR 中时,tomcat 使用 120 MB 内存,而当我将共享库移动到 lib 时,内存使用量增加到 200 MB。这让我感觉它正在为 permgen 中的每个 Web 上下文加载类定义?
猜你喜欢
  • 1970-01-01
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-06
  • 2021-04-28
  • 2013-04-13
相关资源
最近更新 更多