在JavaAgent中停止计划任务

时间:2012-12-25 17:33:13

标签: java timer jmx profiler agent


我试图制作简单的java分析器并使用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?

1 个答案:

答案 0 :(得分:3)

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