• JMX 基础Demo


            JMX在Java编程语言中定义了应用程序以及网络管理和监控的体系结构、设计模式、应用程序接口以及服务。通常使用JMX来监控系统的运行状态或管理系统的某些方面,比如清空缓存、重新加载配置文件等

    优点可以非常容易的使应用程序具有被管理
    伸缩性的架构每个JMX Agent服务可以很容易的放入到Agent中,每个JMX的实现都提供几个核心的Agent服务,你也可以自己编写服务,服务可以很容易的部署,取消部署。
     
    • MBean方式

       一个MBean 是一个遵循特定设计模式的和实现了特定接口的Java对象。MBean管理接口有如下描述:

    1. 可访问的属性值
    2. 可调用的操作
    3. 可以发送的消息
    4. MBean java的构造器

    任何一个作为MBean的java实现的java对象,被注册到代理上后,都可以从代理机构的JVM外管理。

    JMX定义了四周类型的MBean,标准MBean,动态MBean,开放MBean和模型MBean

    1. 标准MBean是最简单的实现,他们的管理接口是通过方法名描述的。MXBean是是一种标准的MBean,它使用开放的MBean概念,在简化代码的同事,达到易于管理的目的。
    2. 动态MBean必须实现特定的接口,但是他们在运行时对外提供管理接口,所以具有很大的灵活性。
    3. 开放MBean是动态MBean
    4. 模型MBean也是动态MBean,它是运行时完全可配置和自我描述的。它们为动态设备层资源提供具有默认行为的一般MBean类。

    这些对

    主要提供接口,允许有不同的实现
    /**
     *定义一个普通的接口
     *
     * @author zhangwei_david
     * @version $Id: HiMBean.java, v 0.1 2015年1月24日 下午1:16:15 zhangwei_david Exp $
     */
    public interface HiMBean {
        /**
         *打招呼
         */
        public void sayHello();
    
        /**
         * 加法计算器
         *
         * @param x
         * @param y
         * @return
         */
        public int add(int x, int y);
    
        /**
         * 获取名称
         *
         * @return
         */
        public String getName();
    
        /**
         *获取缓存大小
         *
         * @return
         */
        public int getCacheSize();
    
        /**
         *设置缓存大小
         *
         * @param size
         */
        public void setCacheSize(int size);
    }
    /**
     *简单实现类
     * @author Lenovo
     * @version $Id: Hi.java, v 0.1 2014年9月26日 下午2:48:09 Lenovo Exp $
     */
    public class HiMbeanImpl implements HiMBean {
    
        private final String     name               = "Reginald";
        private int              cacheSize          = DEFAULT_CACHE_SIZE;
        private static final int DEFAULT_CACHE_SIZE = 200;
    
        /**
         * @see com.cathy.demo.jmx.notifications.HiMBean#sayHello()
         */
        public void sayHello() {
            System.out.println("Hello," + getName());
        }
    
        /**
         * @see com.cathy.demo.jmx.notifications.HiMBean#add(int, int)
         */
        public int add(int x, int y) {
            return x + y;
        }
    
        /**
         * @see com.cathy.demo.jmx.notifications.HiMBean#getName()
         */
        public String getName() {
            return name;
        }
    
        /**
         * @see com.cathy.demo.jmx.notifications.HiMBean#getCacheSize()
         */
        public int getCacheSize() {
            return cacheSize;
        }
    
        /**
         * @see com.cathy.demo.jmx.notifications.HiMBean#setCacheSize(int)
         */
        public void setCacheSize(int size) {
            cacheSize = size;
        }
    
    }
    

    使用 Model MBean 的过程也是下面几步:

    1. 创建一个 MBServer:mBeanServe
    2. 获得管理资源用的 MBean:serverBean
    3. 给这个 MBean 一个 ObjectName:serverMBeanName
    4. 将 serverBean 以 serverMBeanName 注册到 mBeanServer 上去
    /**
     * 
     * 
     * @author zhangwei_david
     * @version $Id: Main.java, v 0.1 2015年6月19日 下午1:10:03 zhangwei_david Exp $
     */
    public class Main {
    
        /**
         *
         * @param args
         * @throws Exception
         */
        public static void main(String[] args) throws Exception {
            //获取Mean的平台服务
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
            // 对即将被注册的MBean 构造一个ObjectName
            ObjectName objectName = new ObjectName("com.cathy.demo.jmx:type=Hi");
            // 创建一个Mbean
            RequiredModelMBean mbean = new RequiredModelMBean();
            HiMbeanImpl hiMbean = new HiMbeanImpl();
            mbean.setManagedResource(hiMbean, "objectReference");
    
            ModelMBeanAttributeInfo name = new ModelMBeanAttributeInfo("name", "java.lang.String",
                "userName", true, true, false, new DescriptorSupport(new String[] { "name=name",
                        "descriptorType=attribute", "getMethod=getName", "setMethod=setName" }));
    
            ModelMBeanOperationInfo sayHello = new ModelMBeanOperationInfo("say Hello", hiMbean
                .getClass().getMethod("sayHello"));
            // 创建一个ModelMBeanOperationInfo
            ModelMBeanOperationInfo getName = new ModelMBeanOperationInfo("get userName", hiMbean
                .getClass().getMethod("getName"));
    
            // 使用ModelMbeanAttributeInfo和ModelMbeanOperationInfo构建一个ModelMBeanInfo对象
            ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport("HiMbean", "Test",
                new ModelMBeanAttributeInfo[] { name }, null, new ModelMBeanOperationInfo[] { sayHello,
                        getName }, null);
            // 向ModelMBean 设置ModelMBeanInfo
            mbean.setModelMBeanInfo(mbeanInfo);
    
            // 将Mbean 注册到MBeanServer
            mbs.registerMBean(mbean, objectName);
            // 一直等待
            System.out.println("Waiting forever...");
            Thread.sleep(Long.MAX_VALUE);
    
        }
    }
    

    运行后的可以通过jconsole看到MBean



     

    通过HTML页面管理MBean

    /**
     * Alipay.com Inc.
     * Copyright (c) 2004-2014 All Rights Reserved.
     */
    package com.cathy.demo.jmx;
    
    import java.lang.management.ManagementFactory;
    
    import javax.management.MBeanServer;
    import javax.management.ObjectName;
    import javax.management.modelmbean.DescriptorSupport;
    import javax.management.modelmbean.ModelMBeanAttributeInfo;
    import javax.management.modelmbean.ModelMBeanInfo;
    import javax.management.modelmbean.ModelMBeanInfoSupport;
    import javax.management.modelmbean.ModelMBeanOperationInfo;
    import javax.management.modelmbean.RequiredModelMBean;
    
    import com.sun.jdmk.comm.HtmlAdaptorServer;
    
    /**
     *
     *
     * @author zhangwei_david
     * @version $Id: Main.java, v 0.1 2015年6月19日 下午1:10:03 zhangwei_david Exp $
     */
    public class Main {
    
        /**
         *
         * @param args
         * @throws Exception
         */
        public static void main(String[] args) throws Exception {
            //获取Mean的平台服务
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
            // 对即将被注册的MBean 构造一个ObjectName
            ObjectName objectName = new ObjectName("com.cathy.demo.jmx:type=Hi");
            // 创建一个Mbean
            RequiredModelMBean mbean = new RequiredModelMBean();
            HiMbeanImpl hiMbean = new HiMbeanImpl();
            mbean.setManagedResource(hiMbean, "objectReference");
    
            ModelMBeanAttributeInfo name = new ModelMBeanAttributeInfo("name", "java.lang.String",
                "userName", true, true, false, new DescriptorSupport(new String[] { "name=name",
                        "descriptorType=attribute", "getMethod=getName", "setMethod=setName" }));
    
            ModelMBeanOperationInfo sayHello = new ModelMBeanOperationInfo("say Hello", hiMbean
                .getClass().getMethod("sayHello"));
            // 创建一个ModelMBeanOperationInfo
            ModelMBeanOperationInfo getName = new ModelMBeanOperationInfo("get userName", hiMbean
                .getClass().getMethod("getName"));
    
            // 使用ModelMbeanAttributeInfo和ModelMbeanOperationInfo构建一个ModelMBeanInfo对象
            ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport("HiMbean", "Test",
                new ModelMBeanAttributeInfo[] { name }, null, new ModelMBeanOperationInfo[] { sayHello,
                        getName }, null);
            // 向ModelMBean 设置ModelMBeanInfo
            mbean.setModelMBeanInfo(mbeanInfo);
    
            // 将Mbean 注册到MBeanServer
            mbs.registerMBean(mbean, objectName);
    
            // 创建一个HtmlAdapterServer MBean
            HtmlAdaptorServer htmlAdaptorServer = new HtmlAdaptorServer();
            // 修改端口号
            htmlAdaptorServer.setPort(8082);
            // 将html适配器MBean 注入到MBeanServer,该处port仅仅是描述
            mbs.registerMBean(htmlAdaptorServer, new ObjectName("Adaptor:name=html,port=8082"));
            // 启动适配器
            htmlAdaptorServer.start();
            // 一直等待
            System.out.println("Waiting forever...");
            Thread.sleep(Long.MAX_VALUE);
    
        }
    }
    

    可以通过 http://localhost:8082/ 访问



     

    点击【type=Hi】进入MBean视图页面



     

    •  MXBean
    /**
     *MXBean参数对象
     * @author zhangwei_david
     * @version $Id: QueueSample.java, v 0.1 2015年6月20日 下午4:30:30 zhangwei_david Exp $
     */
    public class QueueSample {
    
        private final Date   date;
        private final int    size;
        private final String head;
    
        @ConstructorProperties({ "date", "size", "head" })
        public QueueSample(Date date, int size, String head) {
            this.date = date;
            this.size = size;
            this.head = head;
        }
    
        public Date getDate() {
            return date;
        }
    
        public int getSize() {
            return size;
        }
    
        public String getHead() {
            return head;
        }
    }
    
    /**
     *MXBean接口,定义两个操作
     *
     * @author zhangwei_david
     * @version $Id: QueueSamplerMXBean.java, v 0.1 2015年6月20日 下午4:31:34 zhangwei_david Exp $
     */
    public interface QueueSamplerMXBean {
    
        public QueueSample getQueueSample();
    
        public void clearQueue();
    }
    
    /**
     *MXBean的实现类
     * @author zhangwei_david
     * @version $Id: QueueSampler.java, v 0.1 2015年6月20日 下午4:32:19 zhangwei_david Exp $
     */
    public class QueueSampler implements QueueSamplerMXBean {
    
        private Queue<String> queue;
    
        public QueueSampler(Queue<String> queue) {
            this.queue = queue;
        }
    
        public QueueSample getQueueSample() {
            synchronized (queue) {
                return new QueueSample(new Date(), queue.size(), queue.peek());
            }
        }
    
        public void clearQueue() {
            synchronized (queue) {
                queue.clear();
            }
        }
    
    }
    
    /**
     * 测试方法
     * @author zhangwei_david
     * @version $Id: TestMain.java, v 0.1 2015年6月20日 下午4:33:35 zhangwei_david Exp $
     */
    public class TestMain {
        public static void main(String[] args) throws Exception {
            //获取MBeanServer
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    
            //构造一个ObjectName
            ObjectName mxbeanName = new ObjectName("com.example:type=QueueSampler");
    
            // 创建一个队列
            Queue<String> queue = new ArrayBlockingQueue<String>(10);
            queue.add("Request-1");
            queue.add("Request-2");
            queue.add("Request-3");
            // 构造一个mxbean
            QueueSampler mxbean = new QueueSampler(queue);
    
            // 注册mxbean
            mbs.registerMBean(mxbean, mxbeanName);
    
            //等待
            System.out.println("Waiting for incoming requests...");
            Thread.sleep(Long.MAX_VALUE);
        }
    }
    

     

    •  动态MBean

    /**
     * 动态MBean 示例
     * 
     * @author zhangwei_david
     * @version $Id: HelloDynamic.java, v 0.1 2015年6月21日 下午10:53:07 zhangwei_david Exp $
     */
    public class HelloDynamic implements DynamicMBean {
    
        // 管理控件(MBean)属性
        private String                  name;
    
        // 动态创建MBean需要的变量
        private String                  className   = this.getClass().getName();
        // 描述
        private String                  description = "Simple implementation of a dynamic MBean.";
        //管理资源
        private MBeanAttributeInfo[]    attributes;
        // 构造方法
        private MBeanConstructorInfo[]  constructors;
        // 操作
        private MBeanOperationInfo[]    operations;
    
        private MBeanInfo               mBeanInfo;
        // 通知
        private MBeanNotificationInfo[] notifications;
    
        /**
         * 构造方法
         */
        public HelloDynamic() {
            init();
            buildDynamicMBean();
        }
    
        private void init() {
            className = this.getClass().getName();
            description = "Simple implementation of a dynamic MBean.";
            attributes = new MBeanAttributeInfo[1];
            constructors = new MBeanConstructorInfo[1];
            operations = new MBeanOperationInfo[1];
            notifications = new MBeanNotificationInfo[0];
        }
    
        private void buildDynamicMBean() {
            // 构造方法
            Constructor<?>[] ctors = this.getClass().getConstructors();
            constructors[0] = new MBeanConstructorInfo(
                "HelloDynamic(): Constructs a HelloDynamic object", ctors[0]);
            // 属性
            attributes[0] = new MBeanAttributeInfo("name", "java.lang.String", "Name: name string",
                true, true, false);
            // 方法
            MBeanParameterInfo[] params = null;
            operations[0] = new MBeanOperationInfo("print", "print(): print the name", params, "void",
                MBeanOperationInfo.INFO);
            // MBeanInfo
            mBeanInfo = new MBeanInfo(className, description, attributes, constructors, operations,
                notifications);
        }
    
        /**
         *
         * @see javax.management.DynamicMBean#getAttribute(java.lang.String)
         */
        public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException,
                                                    ReflectionException {
            LoggerUtils.info("获取属性:" + attribute);
            if (attribute == null) {
                return null;
            }
            if ("name".equals(attribute)) {
                return name;
            }
            return null;
        }
    
        public AttributeList getAttributes(String[] attributes) {
            LoggerUtils.info("获取属性列表" + attributes);
            if (attributes == null) {
                return null;
            }
            AttributeList reslist = new AttributeList();
    
            for (String attr : attributes) {
                try {
                    Object value = getAttribute(attr);
                    reslist.add(new Attribute(attr, value));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
            return reslist;
        }
    
        /**
         *
         * @see javax.management.DynamicMBean#getMBeanInfo()
         */
        public MBeanInfo getMBeanInfo() {
            return mBeanInfo;
        }
    
        /**
         *
         * @see javax.management.DynamicMBean#invoke(java.lang.String, java.lang.Object[], java.lang.String[])
         */
        public Object invoke(String actionName, Object[] params, String[] signature)
                                                                                    throws MBeanException,
                                                                                    ReflectionException {
            LoggerUtils.info(MessageFormat.format("反射调用方法 {0},参数: {1}>签名 {2}", actionName, params,
                signature));
            if (actionName.equals("print")) {
                print();
            } else if ("dynamicPrint".equals(actionName)) {
                dynamicPrint();
            }
            return null;
        }
    
        /**
         *
         * @see javax.management.DynamicMBean#setAttribute(javax.management.Attribute)
         */
        public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
                                                     InvalidAttributeValueException, MBeanException,
                                                     ReflectionException {
            if (attribute == null) {
                return;
            }
    
            String attrname = attribute.getName();
            Object attrvalue = attribute.getValue();
    
            if ("name".equals(attrname)) {
                if (attrvalue == null) {
                    name = null;
                } else {
                    try {
                        if (Class.forName("java.lang.String").isAssignableFrom(attrvalue.getClass())) {
                            name = (String) attrvalue;
                        }
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    
        /**
         *
         * @see javax.management.DynamicMBean#setAttributes(javax.management.AttributeList)
         */
        public AttributeList setAttributes(AttributeList attributes) {
            if (attributes == null) {
                return null;
            }
            AttributeList reslist = new AttributeList();
            for (Object obj : attributes) {
                Attribute attr = (Attribute) obj;
                try {
                    setAttribute(attr);
                    String attrname = attr.getName();
                    Object attrvalue = attr.getValue();
                    reslist.add(new Attribute(attrname, attrvalue));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return reslist;
        }
    
        private void print() {
            System.out.println(MessageFormat.format("Hello {0}, This is helloDynamic", name));
            // add method dynamic at runtime
            operations = new MBeanOperationInfo[2];
            buildDynamicMBean();
            MBeanParameterInfo[] parameters = null;
            operations[1] = new MBeanOperationInfo("dynamicPrint",
                "dynamicPrint: Runtime generated by print method", parameters, "void",
                MBeanOperationInfo.INFO);
        }
    
        private void dynamicPrint() {
            System.out.println("This is a runtime generated method!");
        }
    
    }
    
    /**
     * 
     * 
     * @author zhangwei_david
     * @version $Id: HelloDynamicAgent.java, v 0.1 2015年6月21日 下午10:53:51 zhangwei_david Exp $
     */
    public class HelloDynamicAgent {
        private static String DOMAIN = "MyDynamicMBean";
    
        /**
         * @param args
         * @throws NullPointerException
         * @throws MalformedObjectNameException
         * @throws NotCompliantMBeanException
         * @throws MBeanRegistrationException
         * @throws InstanceAlreadyExistsException
         */
        public static void main(String[] args) throws MalformedObjectNameException,
                                              NullPointerException, InstanceAlreadyExistsException,
                                              MBeanRegistrationException, NotCompliantMBeanException {
            //创建一个MBean服务对象,DOMAIN类似于java里面的公共package部分
            MBeanServer server = MBeanServerFactory.createMBeanServer(DOMAIN);
            //创建DynamicMBean对象
            HelloDynamic hello = new HelloDynamic();
            //创建一个web适配器服务器,表示我们MBean服务通过web形式来提供给用户管理
            HtmlAdaptorServer htmlserver = new HtmlAdaptorServer();
            htmlserver.setPort(9999);
            //ObjctName对象类似于完整的package
            ObjectName helloname = new ObjectName(DOMAIN + ":name=HelloDynamic");
            ObjectName htmlname = new ObjectName(DOMAIN + ":name=HtmlAdaptor");
            server.registerMBean(hello, helloname);
            server.registerMBean(htmlserver, htmlname);
    
            htmlserver.start();
        }
    
    }
    
    2015-06-21 22:51:17,854 DEBUG LoggerContext[name=sun.misc.Launcher$AppClassLoader@1d16e93, org.apache.logging.log4j.core.LoggerContext@1e7e365] started OK.
    2015-06-21 22:51:17,856 DEBUG Using default SystemClock for timestamps
    22:51:17.863 [Thread-1] INFO  com.cathy.demo.util.LoggerUtils - 获取属性:name
    22:51:21.698 [Thread-1] INFO  com.cathy.demo.util.LoggerUtils - 反射调用方法 print,参数: [Ljava.lang.Object;@107c4b5>签名 [Ljava.lang.String;@a46b89
    Hello David, This is helloDynamic
    

    上述是发布一个Mbean,下面简单介绍一个远程调用一个MBean

    /**
     * Alipay.com Inc.
     * Copyright (c) 2004-2015 All Rights Reserved.
     */
    package com.cathy.demo.jmx.notifications;
    
    import java.lang.management.MemoryUsage;
    import java.text.MessageFormat;
    import java.util.Set;
    
    import javax.management.MBeanServerConnection;
    import javax.management.ObjectName;
    import javax.management.openmbean.CompositeDataSupport;
    import javax.management.remote.JMXConnector;
    import javax.management.remote.JMXConnectorFactory;
    import javax.management.remote.JMXServiceURL;
    
    /**
     *
     * @author zhangwei_david
     * @version $Id: ClientTest.java, v 0.1 2015年6月20日 下午4:52:49 zhangwei_david Exp $
     */
    public class ClientTest {
    
        private static final long   KB_SIZE     = 1024;
    
        private static final String LOG_PATTERN = "{0}: 分配 {1} KB;  最大值 {2} KB; 已使用 {3} KB;  使用率 {4} %";
    
        /**
         *
         * @param args
         * @throws Exception
         */
        public static void main(String[] args) throws Exception {
            JMXServiceURL serviceURL = new JMXServiceURL(
                    "service:jmx:rmi://localhost/jndi/rmi://localhost:9999/jmxrmi");
            JMXConnector jmxc = JMXConnectorFactory.connect(serviceURL);
            MBeanServerConnection msc = jmxc.getMBeanServerConnection();
            // 获取所有的ObjectName
            Set<ObjectName> objectNames = msc.queryNames(null, null);
            for (ObjectName objectName : objectNames) {
                System.out.println("ObjectName:" + objectName.getCanonicalName() + ".");
            }
    
            ObjectName name = new ObjectName("java.lang:type=OperatingSystem");
            System.out.println(msc.getAttributes(name, new String[] { "CommittedVirtualMemorySize",
                                                                      "FreePhysicalMemorySize", "FreeSwapSpaceSize" }));
    
            printLog(msc, "java.lang:name=Metaspace,type=MemoryPool",
                "java.lang:name=Survivor Space,type=MemoryPool",
                "java.lang:name=Eden Space,type=MemoryPool",
                "java.lang:name=Code Cache,type=MemoryPool",
                    "java.lang:name=Tenured Gen,type=MemoryPool");
        }
    
        private static void printLog(MBeanServerConnection msc, String... name) throws Exception {
            for (String string : name) {
                log(string, getUsageByName(msc, string));
            }
        }
    
        private static MemoryUsage getUsageByName(MBeanServerConnection msc, String name)
                throws Exception {
            return MemoryUsage.from((CompositeDataSupport) msc.getAttribute(new ObjectName(name),
                "Usage"));
        }
    
        private static void log(String key, MemoryUsage usage) {
            System.out.println();
            System.out.println(MessageFormat.format(LOG_PATTERN, key, usage.getCommitted() / KB_SIZE,
                usage.getMax() / KB_SIZE, usage.getUsed() / KB_SIZE,
                usage.getUsed() * 100 / usage.getCommitted()));
        }
    }
    

     运行的结果是:

    ObjectName:java.lang:name=Metaspace,type=MemoryPool.
    ObjectName:java.lang:name=Eden Space,type=MemoryPool.
    ObjectName:java.lang:name=Survivor Space,type=MemoryPool.
    ObjectName:java.lang:name=Copy,type=GarbageCollector.
    ObjectName:JMImplementation:type=MBeanServerDelegate.
    ObjectName:java.lang:type=Runtime.
    ObjectName:java.lang:type=Threading.
    ObjectName:java.lang:type=OperatingSystem.
    ObjectName:java.lang:name=MarkSweepCompact,type=GarbageCollector.
    ObjectName:java.lang:name=Code Cache,type=MemoryPool.
    ObjectName:java.nio:name=direct,type=BufferPool.
    ObjectName:java.lang:type=Compilation.
    ObjectName:java.lang:name=Tenured Gen,type=MemoryPool.
    ObjectName:java.lang:name=CodeCacheManager,type=MemoryManager.
    ObjectName:java.lang:type=Memory.
    ObjectName:java.nio:name=mapped,type=BufferPool.
    ObjectName:java.util.logging:type=Logging.
    ObjectName:java.lang:type=ClassLoading.
    ObjectName:java.lang:name=Metaspace Manager,type=MemoryManager.
    ObjectName:com.sun.management:type=DiagnosticCommand.
    ObjectName:com.sun.management:type=HotSpotDiagnostic.
    [CommittedVirtualMemorySize = 33554432, FreePhysicalMemorySize = 3817508864, FreeSwapSpaceSize = 9955905536]
    
    java.lang:name=Metaspace,type=MemoryPool: 分配 5,120 KB;  最大值 0 KB; 已使用 5,025 KB;  使用率 98 %
    
    java.lang:name=Survivor Space,type=MemoryPool: 分配 512 KB;  最大值 8,704 KB; 已使用 0 KB;  使用率 0 %
    
    java.lang:name=Eden Space,type=MemoryPool: 分配 4,480 KB;  最大值 69,952 KB; 已使用 1,244 KB;  使用率 27 %
    
    java.lang:name=Code Cache,type=MemoryPool: 分配 992 KB;  最大值 32,768 KB; 已使用 961 KB;  使用率 96 %
    
    java.lang:name=Tenured Gen,type=MemoryPool: 分配 10,944 KB;  最大值 174,784 KB; 已使用 1,915 KB;  使用率 17 %
    
  • 相关阅读:
    委托事件
    委托使用(2)
    简单的文件流写读
    datalist 分页显示不用PagedDataSource对象
    委托使用(1)
    文件的路径问题
    委托揭秘
    一个简单的文件上传(没有数据库的)
    Quartz 2D 练习2多点触摸画圈
    插件框架精简版 x3py 已在Win/Mac/Linux下测试通过
  • 原文地址:https://www.cnblogs.com/wei-zw/p/8797767.html
Copyright © 2020-2023  润新知