1


我试图制作简单的 java profiler 并使用 javaagent 来监控内存使用情况。这是我的 javaagent 实现的一部分:

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Timer;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.util.Iterator;
import java.util.List;
import java.util.TimerTask;

public class Transformer implements ClassFileTransformer {

    private Notifier notifier;
    private Instrumentation inst;
    private ArrayList<Class> loadedClasses;


    public Transformer(Instrumentation inst) {
        this.inst = inst;
        loadedClasses = new ArrayList<Class>();
        initNotifier();
        Timer time = new Timer();
        MemoryMonitor mm = new MemoryMonitor(notifier);
        time.schedule(mm, 0, 1000);
    }

    public static void premain(String args, Instrumentation inst) {
        inst.addTransformer(new Transformer(inst));
    }

    private void initNotifier() {
        if (notifier != null) return;
        try {
            Registry registry = LocateRegistry.getRegistry(Const.registryPort);
            notifier = (Notifier) registry.lookup(Const.stubName);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }    
}

public class MemoryMonitor extends TimerTask {

    private Notifier notifier;

    public MemoryMonitor(Notifier notifier) {
        this.notifier = notifier;
    }

    @Override
    public void run() {
        try {
            notifier.memoryUsed(monitorMemory());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private double monitorMemory() {
        List memBeans = ManagementFactory.getMemoryPoolMXBeans();
        double used = 0;
        for (Iterator i = memBeans.iterator(); i.hasNext(); ) {

            MemoryPoolMXBean mpool = (MemoryPoolMXBean) i.next();
            MemoryUsage usage = mpool.getUsage();
            used = usage.getUsed() / 1000;
        }
        return used;
    }
}

此代码运行良好,并将有关内存使用情况的数据发送到分析工具。但是 javaagent 在应用程序执行结束后不会停止。
有谁知道在应用程序执行结束后如何停止 javaagent?

4

1 回答 1

3

使用Timer time = new Timer(true);这将使TimerTasks成为守护进程。当主线程退出时,守护线程结束。更多信息在这里

于 2012-12-25T18:06:14.803 回答