您的位置:首页 > 编程语言 > Java开发

JavaME 程序性能调优内存分析工具 Memory Monitor 的使用

2009-11-26 12:29 791 查看
JavaME 程序性能调优内存分析工具 Memory Monitor 的使用
背景:

linux:CentOS release 5.3 (Final)

jdk:jdk1.6.0_16

eclipse:eclipse-SDK-3.4.1-linux

wtk:sun_java_wireless_toolkit-2.5.2_01-linuxi486

问题:

写好的手机地图程序,在模拟器上运行正常,在真机(nokia N72)上运行时,不一会真机死机。

分析:桌面电脑(模拟器)上内存 512 Mb - 2G(作者分配给 eclipse 的堆内存是 512 Mb),不会出现内存被耗尽的情况,KVM 会适时 GC。但手机的内存很小,一般是 128 Kb - 32 Mb,如果操作容器等太频繁,有大量变量变成垃圾对象,还来不及等系统 GC,内存便被耗尽。

解决:每次有大量变量变成垃圾对象时(即没有任何使用对象指向的对象)进行手工 GC,或者设置定时器定时 GC。

下面是内存分析工具 Memory Monitor 的使用步骤。

Memory Monitor 是 SUN 公司的 WTK 自带的堆空间分析器,可以显示运行时的数据。

WTK 根目录 -> bin -> 运行 ktoolbar -> Edit -> Prefereces -> Monitor -> 将 Enable Memory Monitor 选中 -> OK。

下次你启动 eclipse,然后运行 MIDlet 程序的时候,Memory Monitor 就会自动打开,对堆内存进行监控。如图:



图表视图报告了模拟器当前有 6223 个对象,共占用了大约 398 Kb 的堆空间。

有了这个分析工具,就不难发现对象都在什么时候 KVM 在进行垃圾回收了。

由于手机地图每次下载都要进行更新,得到新的显示对象时,产生大量垃圾对象,如果 KVM 不计时回收,如果用户拖放地图频繁,很容易内存耗尽而死机。

所以,“除旧迎新“之时,需要程序员自己进行手工 GC。相关代码如下,其中, myVector 是用来存放地图对象(封装在自定义 JavaBean 中)的容器:

/**
         * 手机地图容器获得新的地图对象
         */
        myVector = imagesFormat();
        
        /**
         * 容器更新,产生大量对象,手工 GC
         */
        System.gc();
        
        showMap = true;
        repaint();


改写之后,模拟器上重新内存分析,内存果然及时被回收。

下图是手机地图 SUN 模拟器运行效果图:




下图是使用手工 GC 前的程序,使用手机地图时,运行内存分析图:



从图中可以看到:在 KVM 自动 GC 之前,如果连续操作地图(即地图高频率下载, Vector 反复重置更新),大量的垃圾对象得不到回收,堆内存占用就会急剧上升,最高时竟达到 2 Mb,所以对于内存比较小的 N72 手机就在这个时候死机了。

下图是使用 GC 后的程序,使用手机地图时,运行内存分析图:



从图中可以看到:程序几乎不依赖于 KVM 的自动 GC。所以,即使连续操作地图,堆内存也一直保持在 96 Kb 左右。这样就解决了内存比较小的 N72 手机内存耗尽的问题了。

作者总结:手工 GC 也会占用系统资源,影响程序性能。所以对于内存较大的手机,如果确定在 KVM 自动 GC 的周期内,程序占用的堆内存不会达到真机内存上限,最好不要在程序中手工
GC。手工 GC 只是解决 N72 等小内存手机内存耗尽问题的权宜之计。到底什么时候手工 GC 而什么时候不用呢?一切以真机性能调试为主。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: