4

我知道Tomcat可以.war在重新部署时重新加载文件,我不需要杀死Tomcat进程并重新启动它。我可以删除.war,等待 Tomcat 取消部署,然后将新的复制.war到 Web 路径。但是,经过多次微不足道的更新战争而没有重新启动Tomcat,是否可能Tomcat无法有效释放内存或导致一些性能问题?假设一个 Tomcat 实例中只有一个 war 应用程序。

4

2 回答 2

5

基本问题是 Java 目前不提供在Java 虚拟机 (JVM)中运行的代码部分之间的任何类型的隔离,就像操作系统对进程所做的那样。您可以在不影响 Windows/Linux/etc 下的另一个进程的情况下杀死一个进程。您所能做的就是确保可以对事物进行垃圾收集。

对于 Tomcat,处理WAR的方式(根据各种规范)要求每个战争都有自己的类加载器,负责运行该代码。当 WAR 被取消部署时,最终结果应该是该类加载器应该被垃圾收集。

不幸的是,垃圾收集器只能处理完全未引用的对象,并且 WAR 代码中可能存在大量微妙的错误,可以禁止这样做,然后每次重新部署都会导致创建另一个类加载器并且没有被破坏所以你有内存泄漏。在 Tomcat 本身内部检测和解决这些类型的错误方面付出了很多努力,但是如果没有 JVM 支持,几乎不可能做到 100% 正确。

除了修复 WAR 之外,唯一的解决方法是重新启动 JVM。

即使在生产中,您也可以使用VisualVM观察内存使用情况,以了解 Tomcat JVM 随着时间的推移会发生什么。

于 2016-11-20T12:23:32.123 回答
0

是的。停止 Tomcat,部署你的新战争,然后重新启动 Tomcat 会干净得多。一个缺点是默认情况下,您的许多应用程序类在有新请求进入您的应用程序之前不会被加载,但这不是一个大问题。只是意味着在对新 WAR 的第一个请求时启动几秒钟。这就是我们在生产中部署战争的方式。

如果新战争阻止 Tomcat 正确启动,我们还允许我们在日志中设置健康检查,然后我们在知道存在问题的情况下回滚战争,但这是一个单独的主题。

停机时间呢?

这可能超出了您的问题范围,但是当您想防止用户看到任何停机时间时,您将运行多个 tomcat 实例并一次部署并重新启动一个。

于 2016-11-21T03:19:18.823 回答