[Design the new POJO MicroContainer] - VFS Performance
by adrian@jboss.org
Besides the AOP usage, the other major thing I'm seeing
using hprof for sampling is the VFS usage by the classloader.
I'll show some typical stacktraces:
Not much we can do about the biggest one,
since this is the JDK parsing the bytecode.
The only way to reduce this, is the reduce the number of classes loaded.
| java.lang.ClassLoader.defineClass1(ClassLoader.java:Unknown line)
| java.lang.ClassLoader.defineClass(ClassLoader.java:620)
| org.jboss.classloader.spi.base.BaseClassLoader.access$200(BaseClassLoader.java:62)
| org.jboss.classloader.spi.base.BaseClassLoader$2.run(BaseClassLoader.java:504)
| org.jboss.classloader.spi.base.BaseClassLoader$2.run(BaseClassLoader.java:464)
| java.security.AccessController.doPrivileged(AccessController.java:Unknown line)
| org.jboss.classloader.spi.base.BaseClassLoader.loadClassLocally(BaseClassLoader.java:462)
| org.jboss.classloader.spi.base.BaseClassLoader.loadClassLocally(BaseClassLoader.java:439)
| org.jboss.classloader.spi.base.BaseDelegateLoader.loadClass(BaseDelegateLoader.java:134)
| org.jboss.classloader.spi.filter.FilteredDelegateLoader.loadClass(FilteredDelegateLoader.java:131)
|
Reading byte code from zip files
| java.util.zip.Inflater.inflateBytes(Inflater.java:Unknown line)
| java.util.zip.Inflater.inflate(Inflater.java:215)
| java.util.zip.InflaterInputStream.read(InflaterInputStream.java:128)
| java.io.FilterInputStream.read(FilterInputStream.java:90)
| org.jboss.virtual.plugins.context.zip.ZipEntryInputStream.read(ZipEntryInputStream.java:112)
| org.jboss.classloader.plugins.ClassLoaderUtils.loadByteCode(ClassLoaderUtils.java:150)
| org.jboss.classloader.spi.base.BaseClassLoader$2.run(BaseClassLoader.java:475)
| org.jboss.classloader.spi.base.BaseClassLoader$2.run(BaseClassLoader.java:464)
| java.security.AccessController.doPrivileged(AccessController.java:Unknown line)
| org.jboss.classloader.spi.base.BaseClassLoader.loadClassLocally(BaseClassLoader.java:462)
|
This looks inefficient, it is listing a parent directory when we do getChild
| java.io.UnixFileSystem.checkAccess(UnixFileSystem.java:Unknown line)
| java.io.File.canRead(File.java:660)
| org.jboss.virtual.plugins.context.file.FileHandler.getChildren(FileHandler.java:161)
| org.jboss.virtual.plugins.context.file.FileSystemContext.createVirtualFileHandler(FileSystemContext.java:337)
| org.jboss.virtual.plugins.context.file.FileSystemContext.createVirtualFileHandler(FileSystemContext.java:256)
| org.jboss.virtual.plugins.context.file.FileHandler.createChildHandler(FileHandler.java:224)
| org.jboss.virtual.plugins.context.AbstractVirtualFileHandler.structuredFindChild(AbstractVirtualFileHandler.java:509)
| org.jboss.virtual.plugins.context.file.FileHandler.getChild(FileHandler.java:233)
| org.jboss.virtual.VirtualFile.getChild(VirtualFile.java:427)
| org.jboss.classloading.spi.vfs.policy.VFSClassLoaderPolicy.findVirtualFileInfo(VFSClassLoaderPolicy.java:488)
|
Modified checking
| java.io.UnixFileSystem.getLastModifiedTime(UnixFileSystem.java:Unknown line)
| java.io.File.lastModified(File.java:795)
| org.jboss.virtual.plugins.context.zip.ZipFileWrapper.getLastModified(ZipFileWrapper.java:140)
| org.jboss.virtual.plugins.context.zip.ZipEntryContext.getLastModified(ZipEntryContext.java:682)
| org.jboss.virtual.plugins.context.zip.ZipEntryHandler.getLastModified(ZipEntryHandler.java:92)
| org.jboss.virtual.plugins.context.DelegatingHandler.getLastModified(DelegatingHandler.java:107)
| org.jboss.virtual.plugins.context.AbstractVirtualFileHandler.hasBeenModified(AbstractVirtualFileHandler.java:181)
| org.jboss.virtual.plugins.context.file.FileHandler.getChildren(FileHandler.java:183)
| org.jboss.virtual.plugins.context.file.FileSystemContext.createVirtualFileHandler(FileSystemContext.java:337)
| org.jboss.virtual.plugins.context.file.FileSystemContext.createVirtualFileHandler(FileSystemContext.java:256)
|
I keep seeing this, not checked if it is a real inefficiency
| org.jboss.virtual.plugins.context.AbstractVirtualFileHandler.getLocalPathName(AbstractVirtualFileHandler.java:230)
| org.jboss.virtual.plugins.context.zip.ZipEntryContext.isLeaf(ZipEntryContext.java:751)
| org.jboss.virtual.plugins.context.zip.ZipEntryHandler.isLeaf(ZipEntryHandler.java:110)
| org.jboss.virtual.plugins.context.AbstractVirtualFileHandler.structuredFindChild(AbstractVirtualFileHandler.java:502)
| org.jboss.virtual.plugins.context.zip.ZipEntryHandler.getChild(ZipEntryHandler.java:139)
| org.jboss.virtual.plugins.context.DelegatingHandler.getChild(DelegatingHandler.java:93)
| org.jboss.virtual.VirtualFile.getChild(VirtualFile.java:427)
| org.jboss.classloading.spi.vfs.policy.VFSClassLoaderPolicy.findVirtualFileInfo(VFSClassLoaderPolicy.java:488)
| org.jboss.classloading.spi.vfs.policy.VFSClassLoaderPolicy.findChild(VFSClassLoaderPolicy.java:452)
| org.jboss.classloading.spi.vfs.policy.VFSClassLoaderPolicy.getResource(VFSClassLoaderPolicy.java:385)
|
Similarly this
| java.util.concurrent.ConcurrentHashMap$Segment.get(ConcurrentHashMap.java:334)
| java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:731)
| org.jboss.virtual.plugins.context.zip.ZipEntryContext.getRoot(ZipEntryContext.java:606)
| org.jboss.virtual.plugins.context.AbstractVirtualFileHandler.getLocalPathName(AbstractVirtualFileHandler.java:230)
| org.jboss.virtual.plugins.context.zip.ZipEntryContext.isLeaf(ZipEntryContext.java:751)
| org.jboss.virtual.plugins.context.zip.ZipEntryHandler.isLeaf(ZipEntryHandler.java:110)
| org.jboss.virtual.plugins.context.AbstractVirtualFileHandler.structuredFindChild(AbstractVirtualFileHandler.java:502)
| org.jboss.virtual.plugins.context.zip.ZipEntryHandler.getChild(ZipEntryHandler.java:139)
| org.jboss.virtual.plugins.context.DelegatingHandler.getChild(DelegatingHandler.java:93)
| org.jboss.virtual.VirtualFile.getChild(VirtualFile.java:427)
|
I'm still seeing the PathTokenizer showing up
| org.jboss.virtual.plugins.vfs.helpers.PathTokenizer.getTokens(PathTokenizer.java:97)
| org.jboss.virtual.plugins.context.AbstractVirtualFileHandler.structuredFindChild(AbstractVirtualFileHandler.java:475)
| org.jboss.virtual.plugins.context.zip.ZipEntryHandler.getChild(ZipEntryHandler.java:139)
| org.jboss.virtual.plugins.context.DelegatingHandler.getChild(DelegatingHandler.java:93)
| org.jboss.virtual.VirtualFile.getChild(VirtualFile.java:427)
| org.jboss.classloading.spi.vfs.policy.VFSClassLoaderPolicy.findVirtualFileInfo(VFSClassLoaderPolicy.java:488)
| org.jboss.classloading.spi.vfs.policy.VFSClassLoaderPolicy.findChild(VFSClassLoaderPolicy.java:452)
| org.jboss.classloading.spi.vfs.policy.VFSClassLoaderPolicy.getResource(VFSClassLoaderPolicy.java:385)
| org.jboss.classloader.spi.base.BaseClassLoader$3.run(BaseClassLoader.java:567)
| org.jboss.classloader.spi.base.BaseClassLoader$3.run(BaseClassLoader.java:564)
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4166367#4166367
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4166367
17 years, 8 months
[Design the new POJO MicroContainer] - KernelRegistry - unnecessary Exception construction
by adrian@jboss.org
I'm seeing this as a "hotspot" during bootstrap.
| org.jboss.kernel.plugins.registry.AbstractKernelRegistry.getEntry(AbstractKernelRegistry.java:89)
| org.jboss.kernel.plugins.dependency.AbstractKernelController.getContext(AbstractKernelController.java:154)
| org.jboss.dependency.plugins.AbstractDependencyItem.resolve(AbstractDependencyItem.java:128)
| org.jboss.dependency.plugins.AbstractDependencyInfo.resolveDependencies(AbstractDependencyInfo.java:143)
| org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:951)
| org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:889)
| org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:834)
| org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:672)
| org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:455)
| org.jboss.system.ServiceController.doChange(ServiceController.java:664)
|
The reason is that it gets called a lot and throws
KernelRegistryEntryNotFoundException
when the context is not installed yet.
Absent doing the work to remove the deprecated KernelReigstry
we should probably just add a findEntry() method
that returns null and use that from the KernelController.
The only reason this call exists is because of the KernelRegistryPlugins
support for which should be moved to the KernelController.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4166363#4166363
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4166363
17 years, 8 months
[Design of AOP on JBoss (Aspects/JBoss)] - Re: AOPConstructorJoinpoint and methodHasSubInstanceMetaData
by kabir.khan@jboss.com
Setting a breakpoint in AnnotatedElementLoader, it fails on
| Method with signature get[int] does not exist on class org.jboss.wsf.framework.deployment.EndpointRecordProcessorDeploymentAspect
|
The stacktrace is:
| Thread [main] (Suspended (breakpoint at line 150 in AnnotatedElementMetaDataLoader))
| AnnotatedElementMetaDataLoader.getComponentMetaDataRetrieval(Signature) line: 150
| AbstractMetaDataContext.getComponentMetaDataRetrieval(Signature) line: 276
| MetaDataRetrievalToMetaDataBridge.getComponentMetaData(Signature) line: 160
| AOPConstructorJoinpoint.methodHasSubInstanceMetaData(MetaData, MethodInfo) line: 171
| AOPConstructorJoinpoint.rootHasMethodWithSubInstanceMetaData(MetaData) line: 149
| AOPConstructorJoinpoint.rootHasSubInstanceMetaData(MetaData) line: 129
| AOPConstructorJoinpoint.dispatch() line: 92
| AbstractListMetaData(AbstractTypeMetaData).createInstance(TypeInfo, ClassLoader, Class<T>, boolean) line: 251
| AbstractListMetaData(AbstractTypeMetaData).getTypeInstance(TypeInfo, ClassLoader, Class<T>, boolean) line: 292
| AbstractListMetaData(AbstractTypeMetaData).getTypeInstance(TypeInfo, ClassLoader, Class<T>) line: 271
| AbstractListMetaData(AbstractCollectionMetaData).getValue(TypeInfo, ClassLoader) line: 109
| PropertyDispatchWrapper.execute() line: 87
| PropertyDispatchWrapper(ExecutionWrapper).execute(AccessControlContext) line: 47
| KernelControllerContextAction.dispatchExecutionWrapper(KernelControllerContext, ExecutionWrapper) line: 109
| ConfigureAction.dispatchSetProperty(KernelControllerContext, PropertyMetaData, boolean, BeanInfo, Object, ClassLoader) line: 109
| ConfigureAction.setAttributes(KernelControllerContext, Object, BeanInfo, BeanMetaData, boolean) line: 87
| ConfigureAction.installActionInternal(KernelControllerContext) line: 44
| ConfigureAction(InstallsAwareAction).installAction(KernelControllerContext) line: 54
| ConfigureAction(InstallsAwareAction).installAction(ControllerContext) line: 42
| ConfigureAction(SimpleControllerContextAction<T>).simpleInstallAction(T) line: 62
| ConfigureAction(AccessControllerContextAction<S,T>).install(ControllerContext) line: 71
| KernelControllerContextActions(AbstractControllerContextActions).install(ControllerContext, ControllerState, ControllerState) line: 51
|
Going back to AOPConstructorJoinPoint, the contained constructorInfo is public java.util.ArrayList(), so it is iterating over ArrayList's methods. However, looking at KernelControllerContextActions the installed bean is of type org.jboss.wsf.framework.deployment.EndpointRecordProcessorDeploymentAspect:
| AbstractKernelControllerContext@cd8e39{ metadata=AbstractBeanMetaData@e6750f{name=WSNativeEndpointRecordProcessorDeploymentAspect bean=org.jboss.wsf.framework.deployment.EndpointRecordProcessorDeploymentAspect properties=[mbeanServer, processors, requires, provides] constructor=null autowireCandidate=true}name=WSNativeEndpointRecordProcessorDeploymentAspect target=org.jboss.wsf.framework.deployment.EndpointRecordProcessorDeploymentAspect@9d0863 state=Instantiated depends=AbstractDependencyInfo@91cb98{idependOn=[AbstractDependencyItem@1de5b9{name=WSNativeEndpointRecordProcessorDeploymentAspect dependsOn=WSMBeanServerLocator whenRequired=Configured resolved=true}, AbstractDependencyItem@d4f822{name=WSNativeEndpointRecordProcessorDeploymentAspect dependsOn=WSMemoryBufferRecorder whenRequired=Configured resolved=true}, AbstractDependencyItem@ee97af{name=WSNativeEndpointRecordProcessorDeploymentAspect dependsOn=WSLogRecorder whenRequired=Configured resolved=true}] unresolved=[AbstractDependencyItem@1de5b9{name=WSNativeEndpointRecordProcessorDeploymentAspect dependsOn=WSMBeanServerLocator whenRequired=Configured resolved=true}, AbstractDependencyItem@d4f822{name=WSNativeEndpointRecordProcessorDeploymentAspect dependsOn=WSMemoryBufferRecorder whenRequired=Configured resolved=true}, AbstractDependencyItem@ee97af{name=WSNativeEndpointRecordProcessorDeploymentAspect dependsOn=WSLogRecorder whenRequired=Configured resolved=true}]}}
|
So it would seem that when creating the properties for the bean, it uses the MetaData for the bean, which does not contain the methods for the properties. Maybe we need to call MetaDataStack.mask() as part of ConfigureAction.setAttributes()?
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4166362#4166362
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4166362
17 years, 8 months
[Design of AOP on JBoss (Aspects/JBoss)] - Dynamic AOP API
by flavia.rainone@jboss.com
As discussed in JBW, we are going to define a new, state of the art Dynamic AOP API for the next JBoss AOP version (after we go GA).
I decided to give the initial kick and start this thread.
Mainly, I see two options here: improving the existing API or coming up with a brand new API (an adaptation layer to our current API)
Improving the existent API would consist mainly of creating more intuitive constructors for AspectDefinition and AdviceBinding (such as removing cflow, and allowing definition of cflow using varargs), and adding more methods to AdviceBinding (addAdvice(Class<?> aspectClass, String adviceName)).
The advantage of doing so is that we stick with our already existing classes.
One of the problems I see with extending the existent API is that we would still force the user to register secondary stuff in the AspectManager, such as cflow and aspect definitions.
Besides, with a new API, we would be free to make dynamic AOP more straighforward, and it could be simpler for the end user to use it if he doesn't have to use AspectManager (I mean, there are so many methods in AspectManager, everything being mixed up in a single class can make users confused).
So, Kabir, what do you have in mind for this?
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4166298#4166298
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4166298
17 years, 8 months