java - Tomcat Classloader 如何在同一个 JVM 中分离不同的 Webapps 对象范围?

标签 java tomcat jvm

由于 Tomcat 可以同时加载多个 webapp,并且这些 webapp 可以单独工作,互不干扰,并且工作在同一个 JVM 中。 所以我很困惑tomcat如何处理同一个JVM中的对象范围。

例如,我在两个不同的 Web 应用程序中都有一个单例对象,而 tomcat 将为每个生成两个不同的单例对象。我一直认为单例对象在同一个JVM中只有一个对象,但在tomcat JVM中可能有两个或更多。


我已经阅读了一些关于 ClassLoader 的信息,Tomcat 有自己的 WebAppClassLoader 来加载 webapps。那么这是否意味着这里的对象范围是 ClassLoader 还是我错了。有谁知道这个或者可以给我一些关于tomcat工作内存布局的信息?

最佳答案

所有的 secret 都在那些 ClassLoader 实例的背后。

类的状态(如所有静态变量、字节码等)由加载该类的类加载器确定范围(一个类在 JVM 中通过其完全限定的名称和加载该类的类加载器来标识。这不完全是一个范围,但将其视为范围通常有助于更好地理解这一点)。

所以如果一个类被两个不同的类加载器加载,这个类在虚拟机中存在两次,它有两组静态字段,可以有不同的字节码(比如不同的方法实现)等等。请注意,即使它们的名称相同,这两个对象也不能相互转换。 “普通”Java 应用程序的所有类都由类加载器层次结构加载,并且每个类只加载一次。

对于更复杂的场景,您将需要不同的行为。有时您希望将库与您的代码隔离开来(例如 eclipse 中的插件或应用程序服务器中的 Web 应用程序)。

将您的程序与其他类隔离的基本思想是使用额外的类加载器加载那些类并使用大量反射。如果您想阅读此内容,请查看 Oracle 在 ClassLoaders 上的文档。或 OSGI .

Tomcat(以及许多其他 Web 容器/应用程序服务器)使用单独的 ClassLoader 层次结构加载应用程序。这将所有类与其他(Web)应用程序隔离开来,从而确保单例、不同的类版本和所有这些东西不会发生冲突。

关于java - Tomcat Classloader 如何在同一个 JVM 中分离不同的 Webapps 对象范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19559210/

相关文章:

c++ - 如何解决 "Didn' t 在路径 : DexPathList in my native callback to Java 上找到类 "..."

jboss - 由于 org.infinispan.util.concurrent.jdk8backported.LongAdder 中的 `EXCEPTION_ACCESS_VIOLATION` 导致 JVM 崩溃

java - 是否可以使用Java/Kotlin在Android MotionLayout中从“开始”状态切换到“结束”状态?

java - 设置 (PNG) 位图颜色而不是逐像素设置的更快方法

java - 如何运行 Resultset.next() 两次?

java - 如何判断app是否被 "Share-Via"调用?

java - OS X 上的 Tomcat 日志文件

java - JVM 是否使用 kotlinc 来实现 Kotlin?

java - 在 eclipse 的 tomcat 中运行一个 java servlet maven webapp

tomcat - junit测试中如何初始化servletContext