使用相同的 jvm 在同一个 tomcat 上运行多个 Web 应用程序。有时,一个存在内存泄漏的Web应用程序会导致整个jvm崩溃并影响其他Web应用程序。有什么建议如何隔离它而不需要使用多个 jvm 和 tomcat
在同一个 JVM 中,所有东西都共享相同的内存。没有系统分配单独的池或配额。
如果您的某个应用程序在这方面表现非常糟糕,您唯一能做的就是在单独的 JVM(单独的 Tomcat)中单独运行它。
应用程序是否作为单独的进程运行?还是同一个?
首先,您应该查看分析以查找内存泄漏https://stackoverflow.com/questions/1716597/java-memory-leak-detection-tools。
但是,作为内部的快速解决方案,您可以使用 Runtime.getRuntime().totalMemory() 来查看正在使用的内存量,如果它增长到超过一定限制,并且您知道哪个应用程序导致了问题,您可以可以重新启动该应用程序。
您还可以尝试运行 System.gc(),这是一种糟糕的方法,并且确实不应该使用,因为它可能会被 JVM 忽略。
据我所知,简短的回答是:不,这是不可能的。 Tomcat 对所有正在运行的应用程序使用单个内存空间。
我下意识的反应是你应该修复内存泄漏,而不是试图隔离行为不当的应用程序。治愈比隔离更好。由于我不知道您的问题的详细信息,也许由于某种原因这不切实际。
您无法隔离同一 JVM 中的应用程序(尽管您可以执行诸如检测特定应用程序类加载器以进行诊断之类的操作)
如果您关心的是管理/配置(而不是总内存消耗),您可以使用catalina.home和catalina.base在同一个安装中运行多个Tomcat实例
JSR 121 旨在解决这个问题,但尚未实现。
Java 中没有标准系统来真正隔离 Web 应用程序使用的内存。
但是,您可以编写一些字节码编织逻辑来跟踪特定应用程序分配了多少内存。如果它超过特定阈值,您可以抛出异常并阻止应用程序分配更多内存。如果您可以跟踪网络应用程序消耗的所有内存,您想做什么?您想实现什么?
请注意,这只能有效地计算出 Web 应用程序已分配了多少内存,而不是当前在系统中消耗了多少内存。为了获得该指标,您必须对所有对象进行字节码编织 Finalize() 。由于 Finalize() 由 JVM 以尽力而为的方式运行,因此如果系统处于负载状态,这可能无法为您提供最准确的值。 JVM 会降低这些终结线程的优先级,即使对象已被清理,您的值也永远不会更新。
为了更新这一点,现在可以在单个 JVM 上运行多个应用程序。应用程序在隔离的 Java 虚拟容器中运行,该容器可以保护您的应用程序免受“吵闹的邻居”的影响,并允许您在应用程序之间共享资源。这为您提供了 Apache Tomcat 的隔离性、弹性和更高的应用程序密度。从 www.elasticat.com 下载它 注意:我为 Waratek 工作,他开发了这个新的 JVM