Reputation: 8161
Let's say I have two classloaders, x
and y
, used for loading ClassX
and ClassY
, respectively, as well as their dependencies. Everything else in the application is loaded using the default classloaders.
Now assume that ClassX
and ClassY
share a dependency, ClassZ
.
If the main application also has a dependency to ClassZ
(whether or not it has actually loaded the class yet), my assumption is that x
/y
won't be used at all to resolve this as the default classloaders should be able to find it. (Please correct me if I'm wrong.)
Now, my main question is what happens if only x
and y
can locate ClassZ
: If both ClassX
and ClassY
reference it, will it be loaded twice (i.e. waste twice as much space in PermGen) or is Java clever enough to detect that it's exactly the same class, loaded by two different classloaders, and just keep one copy in memory?
Upvotes: 3
Views: 139
Reputation: 11999
They will both have their own Class
instance for ClassZ
. Keeping such loading separate is important in various technologies built on Java, such as webservers or Java EE environments that may need to maintain separate contexts for deployed applications.
You are also correct in your assumption that if the parent classloader for ClassX
and ClassY
(assuming it is the same) has loaded ClassZ
, then that one will be used by both its children. At least, that's the default approach. A classloader first delegates lookup to its parent and if that one can't find it, it will try itself. Some custom loaders may override this behaviour, though.
Complex classloader hierarchies can emerge. While this does "waste" some room in the permgen, trying to share resources is often more trouble than it's worth, and will cause compatibility issues or classloader leaks in some frameworks.
Upvotes: 5