Question

Dalvik has this well-known limitation on the number of methods it can have in a single .dex file (about 65,536 of them). My question is whether inherited (but not overridden) methods count against this limit or not.

To make things concrete, suppose I have:

public class Foo {
  public int foo() {
    return 0;
  }
}

public class A extends Foo { }
public class B extends Foo { }
public class C extends Foo { }

For the purposes of the 65,536 method limit, does this count as adding one method, or adding 4? (Or, I guess, to take things to their logical conclusion, does this count as 1 method or 52 methods, considering that java.lang.Object brings 12 methods along too).

As background, I've got a non-trivial number of generated classes with some commonality, and I'm also bumping up against the method limit, so I'm wondering if it's worthwhile to try to abstract some of those out into a class hierarchy in order to buy some time.

Was it helpful?

Solution

An inherited but not overridden method only counts against the method limit if it is ever referenced (called).

In your example, let's say you have the following piece of code

public class main {
    public static void main(String[] args) {
        Foo foo = new A();
        foo.foo();
    }
}

In this case, you are referring to Foo.foo(), which already has a reference, due to the explicit definition. Assuming these 5 classes are the only classes in the dex file, you will have a total of 2 method references*. One for main.main(String[]), and one for Foo.foo().

Instead, let's say you have the following code

public class main {
    public static void main(String[] args) {
        A a = new A();
        a.foo();

        B b = new B();
        b.foo();

        C c = new C();
        c.foo();
    }
}

In this case, since the foo method for each subclass is actually referenced, they will count against your method limit. Your dex file will have 5 method references*.

  • main.main(String[])
  • Foo.foo()
  • A.foo()
  • B.foo()
  • C.foo()

* This count isn't quite accurate, it doesn't take into account the constructor methods that are added to each class behind the scenes. Each constructor calls its superclass' constructor, so we also have a reference to the Object constructor, for a total of 6 additional method references in each case, giving a method count of 8 and 11 respectively.


If in doubt, you can try out various scenarios and use baksmali's raw dump functionality to see what the method list in the dex file actually contains.

e.g.

javac *.java
dx --dex --output=temp.dex *.class
baksmali -N -D temp.dump temp.dex

And then, in the dump file, look for "method_id_item section". This is the list of method references that the 64k limit applies to.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top