V tomto článku se podíváme se na to, jak je
                  možné pomocí nástroje BTrace sledovat vytváření a
                  úklid oken v javovském programu. Budeme sledovat
                  konstruktory a metodu dispose, která
                  provádí úklid. Pokud programátor zapomene zavolat
                  metodu dispose, nastává memory
                  leak. Dále si ukážeme, jak sledovat otevřené
                  soubory. BTrace nás bude informovat o každém otevření
                  či zavření souboru a na naši žádost vypíše seznam
                  právě otevřených souborů. Tyto postupy mohou pomoci
                  odhalit dvě běžné programátorské chyby: neuklizené
                  okno a neuzavřený soubor.
BTrace je nástroj pro sledování javovských
                  programů, který používá dynamickou instrumentaci
                  javovského bajtkódu. Dokáže se připojit k běžícímu
                  programu, změnit jeho třídy a změněné třídy programu
                  podstrčit. BTrace např. může přidat volání našeho
                  kódu při vstupu do metody nebo před opuštěním metody.
                  Kód, který chceme takto „přidat“ k existujícímu
                  programu, zapisujeme do statických metod ve třídě,
                  která je označena anotací @BTrace.
                  Anotací @OnMethod na metodě vybíráme
                  přípojné místo v programu. Následující příklad
                  vytiskne „print entry“ při každém vstupu do metody
                  print ve třídě first.Test.
@BTrace
public class PrintMonitor {
    @OnMethod(
        clazz = "first.Test",
        method = "print",
        location = @Location(Kind.ENTRY))
    public static void onPrint() {
        BTraceUtils.println("print entry");
    }
}
Toto využijeme při sledování oken. Každé okno v
                  javovském programu je instancí třídy java.awt.Window nebo nějakého potomka. Při
                  vytváření okna tedy vždy dojde k zavolání kontruktoru
                  třídy Window. Stačí tudíž sledovat
                  konstruktory této třídy. Abychom měli přehled o
                  vytvořených oknech, budeme si je ukládat do mapy.
                  Klíčem v mapě bude hashCode daného
                  okna a hodnotou bude obsah zásobníku v době vytváření
                  (tím si zapamatujeme, kde k vytvoření okna došlo).
Uvolnění prostředků okna provádí metoda dispose. Dokud ji programátor nezavolá, okno
                  nemůže být uklizeno. Metodu dispose
                  budeme sledovat na všech potomcích třídy Window. Po skončení metody odstraníme záznam
                  o okně z mapy.
@BTrace
public class WindowTracker {
    private static Map<Integer, String> windows = Collections.newHashMap();
    @OnMethod(
        clazz = "java.awt.Window",
        method = "<init>",
        location = @Location(Kind.RETURN))
    public static void onNewWindow(@Self Window self) {
        int hash = BTraceUtils.hash(self);
        String s = BTraceUtils.concat("opened: ", BTraceUtils.str(hash));
        BTraceUtils.println(s);
        String stack = Threads.jstackStr(4);
        Collections.put(windows, BTraceUtils.box(hash), stack);
    }
    @OnMethod(
        clazz = "+java.awt.Window",
        method = "dispose",
        location = @Location(Kind.RETURN))
    public static void onDisposeWindow(@Self Window self) {
        int hash = BTraceUtils.hash(self);
        String s = BTraceUtils.concat("disposed: ", BTraceUtils.str(hash));
        BTraceUtils.println(s);
        Collections.remove(windows, BTraceUtils.box(hash));
    }
    @OnEvent
    public static void printWindows() {
        BTraceUtils.printMap(windows);
    }
}
Metodu označenou anotací @OnEvent
                  můžeme vyvolat po spuštění programu btrace pomocí Ctrl+C a druhé položky z menu.
                  Metoda vypíše všechna otevřená okna, na kterých dosud
                  nebyla zavolána metoda dispose.
Pokud si chcete sledování oken vyzkoušet,
                  nainstalujte si BTrace
                  a stáhněte si zdroják WindowTracker.java.
                  Pro vyzkoušení můžete použít ukázkovou aplikaci TestApp.jar. Nejprve pustíte ukázkovou aplikaci
                
 java -jar TestApp.jar
a pak se k ní připojíte příkazem
 btrace pid
                  monitoring/WindowTracker.java
 pid zjistíte např. programem jps z JDK.
Pro sledování souborů využijeme třídy java.io.FileInputStream a java.io.FileOutputStream. Tím budeme
                  sledovat nejen instance těchto tříd, ale např. i
                  java.io.FileReader a java.io.FileWriter, protože tyto třídy
                  používají interně FileInputStream a
                  FileOutputStream. Třída FileInputStream má tři konstruktory: FileInputStream(File file), FileInputStream(String name) a FileInputStream(FileDescriptor fdObj).
                  Sledovat budeme pouze první dva (kód však lze snadno
                  upravit i pro sledování třetího konstruktoru).
                  Protože konstruktor FileInputStream(String volá konstruktor 
                  name)FileInputStream(File file), stačí nám
                  sledovat pouze konstruktor s parametrem File. Třída FileOutputStream
                  má pět konstruktorů: FileOutputStream(File, 
                  file)FileOutputStream(File file,, 
                  boolean append)FileOutputStream(String name), FileOutputStream(String name, boolean append) a FileOutputStream(FileDescriptor. Sledovat budeme pouze první čtyři.
                  fdObj)
                  Protože konstruktory FileOutputStream(File, 
                  file)FileOutputStream(String a 
                  name)FileOutputStream(String name, volají konstruktor 
                  boolean append)FileOutputStream(File file, boolean append),
                  stačí sledovat jen tento jeden. Podobně by šlo
                  sledovat i jiné třídy, jako např. java.io.RandomAccessFile.
Po skončení konstruktoru FileInputStream nebo FileOutputStream uložíme informaci o souboru
                  do mapy a po provedení metody close
                  tuto informaci odstraníme. Tím budeme mít v každém
                  okamžiku přehled o všech otevřených souborech.
                  Informace z mapy lze vypsat stejným způsobem jako v
                  předchozím případě.
@BTrace
public class FileTracker {
    private static Map<Closeable, String> files = Collections.newHashMap();
    @OnMethod(
        clazz = "java.io.FileInputStream",
        method = "<init>",
        location = @Location(Kind.RETURN))
    public static void onNewFileInputStream(@Self FileInputStream self, File f) {
        String name = str(f);
        Collections.put(files, self, name);
        println(concat("opened for reading: ", name));
    }
    @OnMethod(
        clazz = "java.io.FileOutputStream",
        method = "<init>",
        location = @Location(Kind.RETURN))
    public static void onNewFileOutputStream(@Self FileOutputStream self, File f, boolean append) {
        String name = str(f);
        Collections.put(files, self, name);
        String s = append ? "opened for append: " : "opened for writing: ";
        println(concat(s, name));
    }
    @OnMethod(
        clazz = "java.io.FileInputStream",
        method = "close",
        location = @Location(Kind.RETURN))
    public static void onCloseFileInputStream(@Self FileInputStream self) {
        String name = Collections.remove(files, self);
        if (name != null) {
            println(concat("closed input file: ", name));
        }
    }
    @OnMethod(
        clazz = "java.io.FileOutputStream",
        method = "close",
        location = @Location(Kind.RETURN))
    public static void onCloseFileOutputStream(@Self FileOutputStream self) {
        String name = Collections.remove(files, self);
        if (name != null) {
            println(concat("closed output file: ", name));
        }
    }
    @OnEvent
    public static void printOpenFiles() {
        println("Open files:");
        printMap(files);
        println("--------------------");
    }
}
Pokud si to chcete vyzkoušet, stáhněte si FileTracker.java. K
                  vyzkoušení je možné použít aplikaci Java2Demo z JDK
                  (je v adresáři jdk/demo/jfc/Java2D). Když v tomto
                  programu přepnete na záložku „mix“, dozvíte se, že se
                  zde opakovaně otevírá soubor README.TXT, aniž by
                  docházelo k jeho uzavření.
