• java 堆栈分析


    再次,研究了一个下午的jhat好jmap。从一开始惊呆、懵懂于那样大量而无聊乏味的数据,到现在有那么一点点收货。赶紧记录下来。没办法,悟性太低。。。

    C:UsersAdministrator>jps
    11896
    12528 Jps
    
    C:UsersAdministrator>jps
    11896
    19016 Jps
    5060 HttpServer
    
    C:UsersAdministrator>jmap -dump:file=testJmapa 5060
    Dumping heap to C:UsersAdministrator	estJmapa ...
    Heap dump file created
    
    C:UsersAdministrator>jhat testJmapa
    Reading from testJmapa...
    Dump file created Sat Jul 05 17:08:41 CST 2014
    Snapshot read, resolving...
    Resolving 6940 objects...
    Chasing references, expect 1 dots.
    Eliminating duplicate references.
    Snapshot resolved.
    Started HTTP server on port 7000
    Server is ready.

    jmap导出内存堆栈的。它能够导出java线程某个时刻的整个内存堆栈信息,记录了每一个类、属性、静态常量等等的信息, —— 唯独不包括类的方法等信息。

    jhat 分析jmap导出的内存堆栈。实际上就是提供了一个静态的web server来供查询等等。

    首页有:

    All Classes (excluding platform)

    Package test

    class test.HttpServer [0x269bc990]
    class test.HttpServer2 [0x269bc7d0]
    class test.Test1234 [0x269bc618]

    Other Queries

    同时提供了oql 这么一种内置的查询语法。

    参考http://blog.csdn.net/gtuu0123/article/details/6039474

    同时有一些疑问:

    1 当我通过jmap导出我一个tomcat 的web 应用的时候,遇到:  The VM does not support the attach mechanism 不知道怎么回事

    2 为什么会出现0 instances的情况?(在我这个例子中HttpServer继承HttpServe2继承Test1234,名字随便取的) 难道说,HttpServer创建的时候引用了HttpServer2和Test1234,所以它们会被加载而计算在All Classes中,但是又因为他们没有被创建实例出来,所以count为0 ?

    Instance Counts for All Classes (excluding platform)

    1 instance of class test.HttpServer 
    0 instances of class test.HttpServer2 
    0 instances of class test.Test1234 

    3 Heap Histogram 和Instance Counts for All Classes (including platform) 什么区别? 后者包含更多的信息排序功能、count、total size(展现为table,如果把表格转换为‘直方’ chart的话,就是Histogram 了吧, 理解了Histogram 的含义,一切都好办),而前者只有count。

    4 Show all members of the rootset 为什么这么多内容? 当然,这样问的话,显得幼稚。其实我的意思是,什么样的对象可以成为rootset ? 怎么静态资源会这么多? 为什么每个rootset的路径都那么短(可能是项目不够复杂的原因)? 为什么前两者有from、 而后面的没有from。。。(很好理解,因为静态资源的locale等是由别的类加载的、我们写的类多数是由Thread加载的,所以有from)  为什么jni、system的ClassLoader为null 其他的没有出现ClassLoader属性。。 为什么Java Local References出现了重复的:ServerSocket SocksSocketImpl ReferenceQueue 等出现2次。。。

    Java Local References
    
    Java Local Reference (from java.lang.ref.Reference$ReferenceHandler@0x22960a38) :
    --> java.lang.ref.Reference$ReferenceHandler@0x22960a38 (104 bytes) 
    Java Local Reference (from java.lang.ref.Finalizer$FinalizerThread@0x22960b38) :
    --> java.lang.ref.Finalizer$FinalizerThread@0x22960b38 (104 bytes) 
    Java Local Reference (from java.lang.ref.Reference$ReferenceHandler@0x22960a38) :
    --> java.lang.ref.Reference$Lock@0x22960a30 (8 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> test.HttpServer@0x229bfbd0 (17 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> [Ljava.lang.String;@0x229bfbc0 (8 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> java.net.ServerSocket@0x229bfe68 (20 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> test.HttpServer@0x229bfbd0 (17 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> java.net.Socket@0x229c1680 (23 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> java.net.ServerSocket@0x229bfe68 (20 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> java.net.SocksSocketImpl@0x229c16a0 (112 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> java.net.Socket@0x229c1680 (23 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> java.net.ServerSocket@0x229bfe68 (20 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> java.io.FileDescriptor@0x229c14d0 (20 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> java.net.SocksSocketImpl@0x229c16a0 (112 bytes) 
    Java Local Reference (from java.lang.Thread@0x22960790) :
    --> java.net.SocksSocketImpl@0x229c1410 (112 bytes) 
    Java Local Reference (from java.lang.ref.Reference$ReferenceHandler@0x22960a38) :
    --> java.lang.ref.Reference$Lock@0x22960a30 (8 bytes) 
    Java Local Reference (from java.lang.ref.Finalizer$FinalizerThread@0x22960b38) :
    --> java.lang.ref.ReferenceQueue@0x22960b10 (24 bytes) 
    Java Local Reference (from java.lang.ref.Finalizer$FinalizerThread@0x22960b38) :
    --> java.lang.ref.ReferenceQueue@0x22960b10 (24 bytes) 
    Java Local Reference (from java.lang.ref.Finalizer$FinalizerThread@0x22960b38) :
    --> java.lang.ref.ReferenceQueue$Lock@0x22960b28 (8 bytes) 

    Java Static References 静态资源

    Java Local References ———— 个人的项目代码产生的refs 

    Busy Monitor References

    JNI Global References

    JNI Local References

    System Class References

    —— 这样分类的根据是什么?Finalizer Summary 做什么用的? GC ? 总共出现了多个的ClassLoader呢? 有多个实例的对象,怎么判断它们是否由同一个ClassLoader加载的呢? 为什么非个人写的class的ClassLoader都是null呢?

    总结

    写了一个最简单的java程序

    public class Test1234 {
      public String aaa = "asfaf";
        /**
         * @param args
         * @throws Exception 
         */
        public static void main(String[] args) throws Exception {
            // TODO Auto-generated method stub
            Thread.sleep(1000000000);
        }
    }

    发现,平台需要的类竟然都有

    Total of 6476 instances occupying 504439 bytes.

    1922 instances of class [C 
    1473 instances of class java.lang.String 
    738 instances of class java.util.TreeMap$Entry 
    367 instances of class java.lang.Class 
    333 instances of class [Ljava.lang.Object; 
    199 instances of class java.lang.StringBuilder 
    185 instances of class [Ljava.lang.String; 
    138 instances of class java.io.File 

    ...

    class [C 1922 341440
    class [B 68 43618
    class java.lang.Class 367 27892
    class java.lang.String 1473 23568
    class java.util.TreeMap$Entry 738 15498
    class [Ljava.lang.Object; 333 12800
    class [Ljava.lang.String; 185 4812

     同时发现Test1234的实例为0

    0 instances of class test.Test1234 

    表明它还未被实例化—— 虽然其main方法已经运行了,但是它没有被实例化,所以,其实例变量aaa也没有被创建:

    执行oql :select s.value.toString() from java.lang.String s where /asfaf/(s.value.toString()) ,返回空

    改成这样:

    package test;
    
    public class Test1234 {
    
        public String aaa = "asfaf";
        /**
         * @param args
         * @throws Exception 
         */
        public static void main(String[] args) throws Exception {
            // TODO Auto-generated method stub
            System.out.println(new Test1234().aaa);
            Thread.sleep(1000000000);
            
        }
    
    }

    保证了Test1234有被实例化(同时没有被回收),

    1 instance of class test.Test1234 

    再次执行上面的oql,有返回了,而且,String对象的个数为

    1480 instances of class java.lang.String 

    总实例对象个数发现变化:

    Total of 6496 instances occupying 504334 bytes.

    再改成 :

    package test;
    
    public class Test1234 {
    
        public String aaa = "asfaf";
        /**
         * @param args
         * @throws Exception 
         */
        public static void main(String[] args) throws Exception {
            // TODO Auto-generated method stub
            new Test1234().aaa = null;
            Thread.sleep(1000000000);
            
        }
    
    }

    发现:

    1474 instances of class java.lang.String 

    Total of 6479 instances occupying 504476 bytes.

    执行同样的oql,发现还是有返回,说明,虽然aaa被赋值为null,但是还是没有被那么快的回收。。
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    关于oql

    发现其实它也没什么太多作用,无非就是查询堆中类的发布、赋值情况, —— 可以查询登录密码是否包含其中有效的内存中,从而说明其密码没加密?

    除此之外呢?  。。。

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    看了别的文章, 感觉还是Eclipse Memory Analyzer (Tool)(简称MAT)好用, 因为mat 是可视化的。。

     Mat的优势,不仅仅在于其可视化,

    http://chenxy.blog.51cto.com/729966/759221

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    带着问题学技术:

    给你一个dump出来的bin文件,

    1 如何分析出其当前最耗时间的方法调用,为什么花那么多时间

    2 哪个方法调用的次数最多,为什么

    3 哪个类最占资源—— 一般是String 或者 char[]/byte[],除次之外,要注意哪些类的count/size是非常大的—— 可能程序写的不好,就很占资源了。。

    4 哪个线程最忙,最占时间,

    5 哪个线程最频繁的被启停,就是说启动后执行很短时间,很快又结束

    6 是否存在定时的任务线程

    7 gc占用了多少时间

    8 gc的影响

    9 major gc 和minil gc的发生情况,为什么发生—— 是否有异常,换句话说,异常情况下gc是怎么样的

    关于jvm:

    1 具体有哪些后台线程,分别什么作用,是否可以去掉

    2 各个进程的工作机制是什么。。

    3 爱上

    作为web程序

    1 吞吐量如何—— 即处理request的能力(响应速度,返回时间,最大限制)怎么样

    2 是否安全—— 是否经得起各种攻击。。

    3 设计的是否足够好—— 是否容易维护

  • 相关阅读:
    在微信移动端input file拍照或从相册选择照片后会自动刷新页面退回到一开始网站进入的页面
    华为手机点击按钮跳转链接不生效!!!
    css content 如何自定义生成图标?
    快速上手制作Icon Font
    一款全兼容的播放器 videojs
    video.js使用教程API
    jquery ajax 请求参数详细说明 及 实例
    前端性能优化
    Bootstrap3 CSS样式基本用法总结
    h5页面的公共css
  • 原文地址:https://www.cnblogs.com/FlyAway2013/p/3826237.html
Copyright © 2020-2023  润新知