假设我有两个类加载器x
和y
,分别用于加载ClassX
和ClassY
及其依赖项。应用程序中的其他所有内容都使用默认的类加载器加载。
现在假设ClassX
和ClassY
共享依赖关系ClassZ
。
如果主应用程序也依赖于ClassZ
(无论它是否实际加载了该类),我的假设是x
/ y
将不会被使用根本无法解决这个问题,因为默认的类加载器应该能够找到它。 (如果我错了,请纠正我。)
现在,我的主要问题是,如果只有x
和y
可以找到ClassZ
会发生什么:如果ClassX
和ClassY
同时引用它,它会不会加载两次(即在PermGen中浪费两倍的空间)或者是Java聪明到足以检测到它是完全相同的类,由两个不同的类加载器加载,并且只在内存中保留一个副本?
答案 0 :(得分:5)
他们都会为Class
拥有自己的ClassZ
个实例。在基于Java构建的各种技术中保持这样的加载是很重要的,例如Web服务器或Java EE环境可能需要为已部署的应用程序维护单独的上下文。
如果ClassX
和ClassY
(假设它是相同的)的父类加载器已加载ClassZ
,那么您的假设也是正确的,那么两者都将使用该类加载器它的孩子。至少,这是默认方法。类加载器首先将查找委托给其父级,如果找不到它,它将自行尝试。但是,一些自定义加载器可能会覆盖此行为。
可以出现复杂的类加载器层次结构。虽然这确实“浪费”了permgen中的一些空间,但尝试共享资源通常比它的价值更麻烦,并且会在某些框架中导致兼容性问题或类加载器泄漏。