开发者

How big class hierarchy influence on java performance?

I have class that extends another class, that extend another class.. and so on.

How slow (in percent) class with 100-level hierarchy 开发者_运维知识库level will work, then class with 10-level hierarchy level?


Let's try it out:

class T1 {}
class T2 extends T1{}
class T3 extends T2{}
class T4 extends T3{}
class T5 extends T4{}
class T6 extends T5{}
class T7 extends T6{}
class T8 extends T7{}
class T9 extends T8{}
class T10 extends T9{}
class T11 extends T10{}
class T12 extends T11{}
class T13 extends T12{}
class T14 extends T13{}
class T15 extends T14{}
class T16 extends T15{}
class T17 extends T16{}
class T18 extends T17{}
class T19 extends T18{}
class T20 extends T19{}
class T21 extends T20{}
class T22 extends T21{}
class T23 extends T22{}
class T24 extends T23{}
class T25 extends T24{}
class T26 extends T25{}
class T27 extends T26{}
class T28 extends T27{}
class T29 extends T28{}
class T30 extends T29{}
class T31 extends T30{}
class T32 extends T31{}
class T33 extends T32{}
class T34 extends T33{}
class T35 extends T34{}
class T36 extends T35{}
class T37 extends T36{}
class T38 extends T37{}
class T39 extends T38{}
class T40 extends T39{}
class T41 extends T40{}
class T42 extends T41{}
class T43 extends T42{}
class T44 extends T43{}
class T45 extends T44{}
class T46 extends T45{}
class T47 extends T46{}
class T48 extends T47{}
class T49 extends T48{}
class T50 extends T49{}
class T51 extends T50{}
class T52 extends T51{}
class T53 extends T52{}
class T54 extends T53{}
class T55 extends T54{}
class T56 extends T55{}
class T57 extends T56{}
class T58 extends T57{}
class T59 extends T58{}
class T60 extends T59{}

I was able to instantiate T53, but T54 onwards threw a StackOverflowError.

new T54();

Exception in thread "main" java.lang.StackOverflowError
    at java.lang.ref.Reference.<init>(Reference.java:216)
    at java.lang.ref.FinalReference.<init>(FinalReference.java:16)
    at java.lang.ref.Finalizer.<init>(Finalizer.java:66)
    at java.lang.ref.Finalizer.register(Finalizer.java:72)
    at java.lang.Object.<init>(Object.java:20)
    at java.io.InputStream.<init>(InputStream.java:28)
    at java.io.FileInputStream.<init>(FileInputStream.java:96)
    at sun.misc.URLClassPath$FileLoader$1.getInputStream(URLClassPath.java:1005)
    at sun.misc.Resource.cachedInputStream(Resource.java:61)
    at sun.misc.Resource.getByteBuffer(Resource.java:144)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:256)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

This was done using the default JVM stack size.

For a 100-level hierarchy you will need a larger stack. (You can increase your stack size using Xss.)


"Good JVMs" (whatever that means) cache the results of method resolution. Performance impact therefore should occur only once and even that will likely be minimal. However, on object creation time an instance of every extended class will be created too every constructor of every superclass will be called, which might result in a bigger impact when creating a lot of objects that have large hierarchies.

I have to concur with Jon Skeet (well, who doesn't) in that the question sounds like there are some serious design issues or a code generator gone rogue. It's akin to asking "how many columns does a database table support". If it's more than reasonable, you're probably doing it wrong.


That will depend on your JVM, the exact operations you're performing, whether various methods are overridden etc.

I would be far more concerned about the design and readability impact than the performance impact, however. Is this really the best design you can come up with? What problem does it solve that couldn't be better solved in a different way?


As per the Java2 Complete Reference Author Herbert Schildr :

However, you can inherit any no of class, level of Java Class Inheritance over 5 is not more appreciable. This will always reduce the performance.

I am also agree with Jon Skeet answer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜