Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正在加载到堆中的Webapp类路径和类_Java_Classpath - Fatal编程技术网

Java 正在加载到堆中的Webapp类路径和类

Java 正在加载到堆中的Webapp类路径和类,java,classpath,Java,Classpath,如果我有两个webapp,它们的web inf/lib目录中都有相同的第三方库jar,比如log4j……当加载第一个webapp并创建一个log4j类时,这个类被加载到堆中。当第二个webapp加载并尝试加载log4j类时,它会在堆中找到该类并使用该类吗?或者它会将自己的类副本加载到堆中吗 嗯,我认为这主要是一个类加载器问题,它仍然取决于您使用的应用程序服务器,但我猜大多数应用程序都使用一个JVM,并为每个正在运行的webapp保留一个类加载器,这样您就可以使用不同版本的同一jar/CLASE同

如果我有两个webapp,它们的web inf/lib目录中都有相同的第三方库jar,比如log4j……当加载第一个webapp并创建一个log4j类时,这个类被加载到堆中。当第二个webapp加载并尝试加载log4j类时,它会在堆中找到该类并使用该类吗?或者它会将自己的类副本加载到堆中吗

嗯,我认为这主要是一个类加载器问题,它仍然取决于您使用的应用程序服务器,但我猜大多数应用程序都使用一个JVM,并为每个正在运行的webapp保留一个类加载器,这样您就可以使用不同版本的同一jar/CLASE同时运行不同的webapp

例如,在tomcat中,如果您需要一些共享库,您可以使用/tomcat/shared/lib文件夹来放置所有Web应用程序都可以访问的JAR


否则是的,不同的webapp不会共享同一堆,这意味着webapp可以访问运行在同一应用服务器上的其他webapp创建的对象

嗯,我认为这主要是一个类加载器问题,它仍然取决于您使用的应用服务器,但我想他们中的大多数都使用一个JVM,并为每个运行的webapp保留一个类加载器,这样就可以让不同的webapp使用相同jar/CLASE的不同版本一起运行

例如,在tomcat中,如果您需要一些共享库,您可以使用/tomcat/shared/lib文件夹来放置所有Web应用程序都可以访问的JAR

否则,是的,不同的webapp不会共享同一堆,这意味着webapp可以访问运行在同一应用程序服务器上的其他webapp创建的对象

不,不应该

事实类加载到堆上在这里毫无意义。因为每个类加载器都维护它自己加载的类列表

然而,类加载器也被组织成一棵树,它们应该要求它们的父类加载器首先尝试加载类,如
ClassLoader
类的javadoc中所述

ClassLoader类使用委托模型来搜索类和资源。类加载器的每个实例都有一个关联的父类加载器。当请求查找类或资源时,类加载器实例将在尝试查找类或资源本身之前,将对该类或资源的搜索委托给其父类加载器

但是,Web服务器通常不遵循此委托模型,以避免Web服务器本身使用的库被Web应用程序拾取。(此行为有时是可配置的,但取决于您使用的Web服务器。)

因此,在实践中,每个webapp都应该有自己独立的类空间,独立于所有其他webapp,因此它们甚至可以使用同一库的两个不同版本,而不会出现任何问题

另一个重要的教训是,由两个不同的类加载器加载的同一个类文件实际上是堆中两个独立的类,并且一个类中的对象将与另一个类不兼容。

不,它不应该兼容

事实类加载到堆上在这里毫无意义。因为每个类加载器都维护它自己加载的类列表

然而,类加载器也被组织成一棵树,它们应该要求它们的父类加载器首先尝试加载类,如
ClassLoader
类的javadoc中所述

ClassLoader类使用委托模型来搜索类和资源。类加载器的每个实例都有一个关联的父类加载器。当请求查找类或资源时,类加载器实例将在尝试查找类或资源本身之前,将对该类或资源的搜索委托给其父类加载器

但是,Web服务器通常不遵循此委托模型,以避免Web服务器本身使用的库被Web应用程序拾取。(此行为有时是可配置的,但取决于您使用的Web服务器。)

因此,在实践中,每个webapp都应该有自己独立的类空间,独立于所有其他webapp,因此它们甚至可以使用同一库的两个不同版本,而不会出现任何问题


另一个重要的教训是,由两个不同的类加载器加载的同一类文件实际上是堆中的两个独立类,一个类中的对象将与另一个类不兼容。

最后一句话,如果它们不共享同一堆,这难道不意味着他们无法访问由其他Web应用程序创建的对象吗?他们只有在同一堆中才能访问其他人,对吗?或者我误解了……好吧,类定义存储在永久生成(非堆)空间中。现在堆空间包含类的实例,然后是使用“new”创建的任何对象。现在,从应用程序服务器的角度来看,我不能确定内部是如何工作的,但我猜它的行为“就像”每个webapp分配了一个JVM,以便不让webapp相互交互。因此,一个给定的webapp无法访问另一个webapp的内存空间。现在,如果您使用tomcat,多个webapp将共享同一个JVM,因此将共享相同的内存空间。我仍然无法看到一个webapp在没有引用的情况下访问另一个webapp创建的对象。例如,对于Log4J,您的两个webapp将有自己的类加载器,然后它们都有自己的Log4J类和一个实例(同样,允许您使用Log4J v2和webapp B Log4J v3创建webapp a)。最后一句话,如果它们不共享同一堆,这难道不意味着他们无法访问由其他Web应用程序创建的对象吗?他们只有在同一堆中才能访问其他人,对吗?还是我误解了