2011-10-18 8 views
7

Użyłem narzędzia MAT w Eclipse do zbadania problemu z wyciekiem pamięci. Zauważyłem, że wyciek został spowodowany przez anonimową instancję klasy wewnętrznej w mojej aplikacji. Nazwa klasy wyświetlana w MAT to com.mycompany.myproduct.MyActivity 3 USD. W MyActivity.java zdefiniowano wiele anonimowych klas wewnętrznych. Skąd mam wiedzieć, która klasa wewnętrzna com.mycompany.myproduct.MyActivity 3 $ oznacza?jak ustalić, która wewnętrzna anonimowa klasa jest wskazywana przez nazwę klasy?

Dzięki.

Odpowiedz

4

W kompilatorze Oracle są one ponumerowane zgodnie z kolejnością występowania w klasie. Nie jestem pewien, czy jest to część jakiejkolwiek specyfikacji, czy zgodna z innymi implementacjami.

Można dekompilować klasę - JD-GUI to świetne narzędzie do tego - a potem zobaczysz, co chcesz wiedzieć. Możesz nawet po prostu przejść z podstawowym demontażem za pomocą javap -c. Dowiesz się z grubsza, gdzie występują zajęcia.

0

Cały punkt anonimowych zajęć polega na tym, że są po prostu tym. Jak się okazało, nie jest łatwo ustalić, z którego pochodzi. Zwykle numeracja zaczyna się od jednego, więc domyślam się, że będzie to trzecia deklarowana klasa anonimowa, która jest twoim problemem.

W tej sytuacji lepiej może zreorganizować swój kod, aby nie mieć żadnych anonimowych klas. W przeciwnym razie sugeruję dołączenie debuggera i wprowadzenie kodu.

1

Podczas bezpiecznej kompilacji kodu masz MyActivity $ 1.class, MyActivity $ 2.class, MyActivity $ 3.class i tak dalej. Możesz użyć dekompilatora java (nad twoją .class), aby zidentyfikować klasę anonymus, która rzuca wyjątek.

4

Podpowiedź: debugger jakoś wie, które klasy są gdzie. Więc możesz też!

Spróbuj użyć javap na tym przykładzie z dwóch klas anonimowych:

import java.util.*; 

public class Test { 
    public static void main(String [] args) { 
     Map m = new HashMap(){{System.out.print(1);}}; 
     Map m1 = new HashMap(){{System.out.print(2);}}; 
    } 
} 

skompilować i uruchomić javap -c -l:

$ javap -c -l Test 
Compiled from "Test.java" 
public class Test extends java.lang.Object{ 
public Test(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

    LineNumberTable: 
    line 3: 0 



public static void main(java.lang.String[]); 
    Code: 
    0: new #2; //class Test$1 
    3: dup 
    4: invokespecial #3; //Method Test$1."<init>":()V 
    7: astore_1 
    8: new #4; //class Test$2 
    11: dup 
    12: invokespecial #5; //Method Test$2."<init>":()V 
    15: astore_2 
    16: return 

    LineNumberTable: 
    line 5: 0 
    line 7: 8 
    line 9: 16 



} 

Jak widać, pierwsza klasa dostał imię Test$1, drugi - Test$2. Nadzieja tat pomaga.

Aby uzyskać bardziej szczegółowe informacje, należy dekompilować konkretne zajęcia, które Cię interesują, np. javap -c -l Test\$2. Zwróć uwagę na numery linii: podadzą ci wskazówkę, gdzie w pliku źródłowym została zdefiniowana klasa.

Powiązane problemy