关注性能: 边缘剖析 - 编程入门网
序令我们失望,不妨试一试。于是我们开始扫描开放源 代码剖析程序。
关注性能: 边缘剖析(2)时间:2011-08-13 IBM Jack Shirazi重新开始 我们首先寻找那些看来是用于内存分析的剖析程序。一号开发源代码内存剖析程序看起来绝对简单, 也许过于简单了。输出结果用处不大,只有一个类列表和每个类的对象个数。但无论如何这也算是一个不 错的起点。它崩溃了。我们陷入了重走老路的担忧。二号开放源代码剖析程序甚至比一号还简单,虽然它 实际上给出了更详细的信息:每个对象都有堆占转储记录,说明对象的大小和所属的类。和其他剖析程序 一样,我们用较低的配置尝试,于是可以看到堆转储逐渐增大——大致就是堆的大小,然后,我们看到的 是一个 1 GB 的输出文件。我们尝试了它,它击溃了虚拟机。但它确实让我们看到了部分堆转储。 在处理像这种很大的因素时,必须能够判断所需资源的数量级和要花费的时间。转存 1 GB 的文件可 能要花很多时间。如果没有考虑到一个操作可能花费多长的时间,您可能错误地认为进程被挂起了,而实 际上它仍然在运行,只是要花费转储 1 GB 格式化文本所需要的时间。这个开放源代码剖析程序正在工作 ,但是第一次测试时我们忽视了给它足够的时间。更遭的是,第一次还没有结束的时候,我们又迫使它进 行第二次转储,结果造成了崩溃。所幸的是,我们认识到问题在我们自己而不是剖析程序,有了较多的认 识之后,我们再次进行了尝试并取得了成功。 heapprofile 剖析程序 那么,到底哪个剖析程序成功了呢?它就是 Matthias Ernst 编写的“heapprofile”。它仅用了一页 C 代码,使用 Java Virtual Machine Profiler Interface (JVMPI) 把堆转存成最简单的格式。甚至还 要自己编译,网站上(请参阅 Resources)没有提供预编译的可执行文件。这种简单性正是我们在这个问 题里所需要的。没有任何开销。除了绝对必要的之外,没有使用堆或者 JNI 资源。程序运行的时候它什 么也不做,当我需要堆转储的时候,它仅仅遍历一次堆,直接将每个对象的大小和类转存到一个文件,没 有在内存中创建任何结构,正是这种结构让其他所有剖析程序击溃了 JVM。 当然,事情还没有完。现在我们需要分析结果数据,使用它确定应用程序所用的对象。幸运的是,输 出格式很容易解析。一旦找到了造成问题的对象,我们还需要找到分配这些对象的地方。为了降低开销, 我们采用重新编译这几个类的简单策略,在构造函数中放上栈跟踪程序,Jack 的著作(请参阅 Resources)中详细描述了这种技术。这种简单的技术需要在构造函数中创建(而不是抛出)异常。异常 中包含分配地点的栈踪迹。然后可以将所有对象的这些栈列成表格。因为多数栈都是相同的,标识调用栈 以及链接到每个栈的相关实例个数需要存储的数据并不很多(最多几千个字符串)。 简单而丑陋 这都是些简单的技术,但并没有很高的生产率。我们更愿意使用功能完备的剖析程序输出数据,尤其 是因为它们提供的数据更便于分析。我们本来希望从堆的根开始,向下跟踪较大的节,直到发现大量引用 堆的对象,但是我们没有选择这个方法。 和通常使用调优技术相比,这次使用的技术比较简陋。但最终我们发现了一些完全不需要的对象,使 用一些类的不同实现可以完全消除它们;另一些必需的对象也可以苗条一点,或者压缩到一起,减少其空 间需求。对象缩减通常都是如此,胖客户机减肥也没有一定之规。和人类一样,让 Java 应用程序节食也 是很困难的事情。也和节食一样,去掉身上多余的脂肪往往比您所想的要花费更长时间。令人遗憾的是, 虽然我们从这个胖客户机上刮掉了两百兆字节,但它仍然没有瘦到足以容纳“真正的”内存剖析程序的运 行。 结束语 我 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |