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

 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 就会自动打开,对堆内存进行监控。如图:

Memory Monitor
        图表视图报告了模拟器当前有 6223 个对象,共占用了大约 398 Kb 的堆空间。
        有了这个分析工具,就不难发现对象都在什么时候 KVM 在进行垃圾回收了。
        由于手机地图每次下载都要进行更新,得到新的显示对象时,产生大量垃圾对象,如果 KVM 不计时回收,如果用户拖放地图频繁,很容易内存耗尽而死机。
        所以,“除旧迎新“之时,需要程序员自己进行手工 GC。相关代码如下,其中, myVector 是用来存放地图对象(封装在自定义 JavaBean 中)的容器:


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

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

手机地图模拟器运行图

        下图是使用手工 GC 前的程序,使用手机地图时,运行内存分析图:
the memory monitor before GC in the code
        从图中可以看到:在 KVM 自动 GC 之前,如果连续操作地图(即地图高频率下载, Vector 反复重置更新),大量的垃圾对象得不到回收,堆内存占用就会急剧上升,最高时竟达到 2  Mb,所以对于内存比较小的 N72 手机就在这个时候死机了。
        下图是使用 GC 后的程序,使用手机地图时,运行内存分析图:
the memory monitor after GC in the code
        从图中可以看到:程序几乎不依赖于 KVM 的自动 GC。所以,即使连续操作地图,堆内存也一直保持在 96 Kb 左右。这样就解决了内存比较小的 N72 手机内存耗尽的问题了。


        作者总结:手工 GC 也会占用系统资源,影响程序性能。
所以对于内存较大的手机,如果确定在 KVM 自动 GC 的周期内,程序占用的堆内存不会达到真机内存上限,最好不要在程序中手工 GC。手工 GC 只是解决 N72 等小内存手机内存耗尽问题的权宜之计。到底什么时候手工 GC 而什么时候不用呢?一切以真机性能调试为主。

posted @ 2009-11-26 12:29  Defonds  阅读(27)  评论(0编辑  收藏  举报