While debugging through performance and boot time issues, we have been seeing that the
BaseClassLoader.loadClass() which is backed by a VFSClassLoaderPolicy is consistently
expensive. A call to BaseClassloader.loadClass() results in the following flow:
1) BaseClassLoader.loadClass() leads to loadFromDomain
2) The BaseClassLoaderDomain internally starts looking for loaders through findLoader()
3) The findLoader() invokes findLoaderInExports() which tries to look for the correct
loader in the "EXPORT"
4) This ultimately leads to the VFSClassLoaderPolicy.getResource() which through it's
findChild() API, starts
traversing the jar(s).
5) This traversing ultimately leads to AbstractVirtualFileHandler.structuredFindChild
which consistently appears as an expensive operation given that it does:
* ZipEntryHandler.isLeaf() - Haven't looked at why the isLeaf implementation contains
the logic that it has right now.
* PathTokenizer.getTokens() - Lot of string manipulations
* ZipEntryHandler.createChildHandler() - Haven't looked at it.
Here's the code from AbstractVirtualFileHandler.structuredFindChild
http://anonsvn.jboss.org/repos/jbossas/projects/vfs/branches/Branch_2_1/s...:
| /**
| * Structured implementation of get child
| *
| * @param path the path
| * @return the handler or <code>null</code> if it doesn't exist
| * @throws IOException for any error accessing the virtual file system
| * @throws IllegalArgumentException for a null name
| */
| public VirtualFileHandler structuredFindChild(String path) throws IOException
| {
| checkClosed();
|
| // Parse the path
| List<String> tokens = PathTokenizer.getTokens(path);
| if (tokens == null || tokens.size() == 0)
| return this;
|
| // Go through each context starting from ours
| // check the parents are not leaves.
| VirtualFileHandler current = this;
| for (int i = 0; i < tokens.size(); ++i)
| {
| if (current == null)
| return null;
|
| String token = tokens.get(i);
| if (PathTokenizer.isCurrentToken(token))
| continue;
|
| if (PathTokenizer.isReverseToken(token))
| {
| VirtualFileHandler parent = current.getParent();
| if (parent == null) // TODO - still IOE or null?
| throw new IOException("Using reverse path on top file handler:
" + current + ", " + path);
| else
| current = parent;
|
| continue;
| }
|
| if (current.isLeaf())
| {
| return null;
| }
| else if (current instanceof StructuredVirtualFileHandler)
| {
| StructuredVirtualFileHandler structured =
(StructuredVirtualFileHandler)current;
| current = structured.createChildHandler(token);
| }
| else
| {
| String remainingPath = PathTokenizer.getRemainingPath(tokens, i);
| return current.getChild(remainingPath);
| }
| }
|
| // The last one is the result
| return current;
| }
|
I haven't yet browsed completely through any of this code. But the classloader
performance is appearing as one of the expensive operations in every profiled snapshot
that i have, not just at deployment time but at runtime too.
Thoughts on how this can be improved?
P.S: Although during boot time analysis of AS, i had mentioned that classloading backed by
VFS was showing up as one of the expensive operation, at that time i had highlighted that
it was affecting deployment time of the application. That issue is a separate one where
the deployer used to traverse the jar(s) to find the package name capabilities of that
jar.
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4250746#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...