J2ME内存占用详解及优化方法

转载 2007年10月11日 14:22:00
【引自CoCoMo的博客】我想做过J2ME的人,特别是像我这样做手机游戏的,肯定会对OutOfMemoryError这个异常深恶痛绝,尤其是在老40这样变态的机型上,甚至对这个异常都产生了恐惧。还好我现在总算不做这个机型了,对那些仍然在为这个机型移植游戏的同志们感到同情。为了能够稍微缓解一下他们的痛苦,也为了广大J2ME的从业者和爱好者能尽量减少与该异常的见面次数,CoCoMo将把自己的经验分享一下。

首先了解一下分析内存占用的方法,一般有两种:模拟器自带工具和Runtime类方法。

模拟器自带工具:WTK貌似带了一个Memory Monitor,而且许多学者人士也夸夸其谈他的使用方法,但我不知道有多少人真正在用。就我对他的了解,首先运行他你的程序会慢的一塌糊涂,这对游戏开发者来说简直是无法忍受的。但我出于研究目的仍然让他跑了半个小时才发现原来他根本无法显示正确的内存占用量,我载入一张很大的图片后他的内存线好像只出现了微微的波动又停留在原位,呵,看来的确是拿出来秀的。我一般使用的是7210模拟器自带的内存监视器,模拟的很准,但唯一的缺点是内存太少,才200K。我也见某些人使用3220的模拟器监视内存,好像内存稍微大一点,我还没来得及尝试就再也不用为老40写程序了,庆幸。

Runtime类方法:我经常用这个语句System.out.println(Runtime.getRuntime().freeMemory());后来集成进了我的引擎,他能够显示当前剩余内存。不记得有多少次我用它在老40上来寻找内存占用峰值。

了解了分析内存的方法,来看看内存占用的罪魁祸首:程序和资源。

程序:类会被编译成class字节码文件随MIDlet的启动加载进内存,而且是一次性全部加入。也就是说MIDlet里类个数越多、单个类程序越长、类内字符串常量及数据越多,编译后的class文件就越大,载入后占用的内存也越多。我经常在MIDlet类的构造函数里用Runtime方法来查看MIDlet启动后整个程序占用内存量。

优化方法:

1.某些同志将MIDlet程序写成两个类来减少内存占用量,但是以牺牲Java的OOP特性为代价的。在程序比较大时这种弊端将尤为显见。而且CoCoMo曾经遇到过单个类过大,载入时间过长而违反百宝箱有关Logo 6秒时间限制的情形。因而我现在的程序加带引擎一般都是6-7个类。

2.尽量编写优雅的代码,减少函数数量,在程序发布时去掉try catch,最大限度的减少程序行数,这一般都是在老40上没有办法的办法,现在CoCoMo已经不靠这个来省内存了。

3.将数据及字符串写进文件,在用时方载入内存,不用时设为null。

4.I/O操作getClass().getResourceAsStream(file);、数据库操做RecordStore.openRecordStore(name, true);、声音创建Manager.createPlayer();、图像创建Image.createImage(file);会在短时间内占用大量内存且过后释放,如果MIDlet程序内存剩余量不足则会在这些函数频繁调用时发生内存溢出,产生所谓的内存峰值,尤其在老40上比较普遍。当你再次与讨厌的OutOfMemoryError碰面时,多用Runtime查找内存峰值发生位置并尽量将这些语句分开调用,并灵活运用System.gc()来及时回收。

资源:

图片:是占用内存的大户,尤其是手机游戏图片资源众多。对图片资源在内存中占用量的计算成为J2ME游戏开发者的经常性工作,CoCoMo来解释一下如何计算图片在内存中的占用量:

内存占用量=宽*高*像素字节数,其中像素字节数因机型而异。

例如一张64*64的图片在7210上的内存占用量=64*64*1.5=6144(字节)=6K、在S60上的内存占用量=64*64*2=8192(字节)=8K。像素字节数因机型而异,例如7210是4096色机型,也就是说用12位来表示一个像素,所以乘上1.5,而S60是65536色的机型,用16位来表示一个像素,所以乘上2。

优化方法:

有些人认为压缩图片可以节省内存,这种想法是错误的。根据上面的解释图片载入内存后只和宽高有关系,和图片数据量大小没有任何关系,压缩图片只能减少jar大小而不能减少内存占用量。

1.静态法:减小图片大小,宽高小了结果当然小了。根据这个思路出现了动画编辑器之类的工具,像gameloft的波斯王子,人物被分割后使人体的部位可以重用,各部位紧凑放置都是为了较少图片大小,充分利用图片中的每一寸空间。

2.动态法:减少同一时刻载入内存的图片数。CoCoMo曾经在火影武士项目中遇到过这种情况,当时有6种怪物,如果同时载入内存在老40上肯定爆掉了,但是每关只出现两到三种怪物,所以每一关只需要载入该关出现的怪物图片即可。现在想起来当时做这个项目在老40上溢出频出,真把我搞死了。

声音:声音也是比较耗用内存的资源,声音中音轨所占的byte会转化成字节流被载入到内存中。因而减少音轨所占byte即可减少内存耗用量。目前gameloft的做法是用声音转化工具将mid转化为ott,然后变为ByteArrayInputStream字节流来创建Player。  

ANDROID内存优化(大汇总——上)

ANDROID内存优化以及原理大汇总,本文包括内存简单介绍,堆栈特性对比,分析Android系统内存和堆内存的方法工具介绍。...
  • a396901990
  • a396901990
  • 2014年08月15日 00:20
  • 29417

J2ME内存优化方法

内存会溢出肯定和代码逃不了关系,99.99%学java的人都知道垃圾回收器是java的一大优点并据此来嘲笑C++。显然这个特性为代码编写者省了不少事,但这个特性却带来了不少隐患。   out m...
  • u014571355
  • u014571355
  • 2014年04月28日 20:02
  • 497

[Unity优化]减少内存占用:贴图优化

参考链接: http://blog.csdn.net/u010153703/article/details/45502895 http://blog.csdn.net/candycat1992...
  • lyh916
  • lyh916
  • 2015年03月07日 11:46
  • 2389

linux 内存占用情况查看并优化

1. 使用top 查看内存的占用情况,该命令类似于windows系统的内存管理器, 然后键入"M"命令根据内存的占用情况降序排列,看看内存主要由哪些进程占用。("P"是CPU占用情况降序排列) ...
  • u013552365
  • u013552365
  • 2017年05月23日 11:18
  • 1450

ANDROID内存优化(大汇总——中)

ANDROID内存优化大汇总,从各个方面去介绍如何减少内存开销和重用资源
  • a396901990
  • a396901990
  • 2014年08月29日 00:08
  • 36168

Android内存优化大全(中)

转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon...
  • hewence1
  • hewence1
  • 2014年09月02日 11:50
  • 77532

Redis内存使用优化与存储

Redis数据类型 最为常用的数据类型主要有五种:String, Hash, List, Set和SortedSet. redis内部使用一个redisObject对象来表示所有的key和value。...
  • u013256816
  • u013256816
  • 2016年04月12日 14:24
  • 17039

JVM内存优化——小试牛刀

最近在拜读周志明的《深入理解Java虚拟机》,看了Java的内存管理机制以及Jvm优化相关内容。于是,下载了sun提供的Jvm检测工具VisualVm。下载地址:https://visualvm.ja...
  • supercooly
  • supercooly
  • 2016年09月09日 01:59
  • 1167

《C++高效编程:内存与性能优化》第九章:高效内存管理

  • ywcpig
  • ywcpig
  • 2016年09月14日 21:05
  • 687

iOS开发-18个性能优化/内存优化常用方法(很常用)

1. 用ARC管理内存 ARC(Automatic ReferenceCounting, 自动引用计数),它避免了最常见的由于我们忘记释放内存所造成的内存泄露。它自动为你管理retain和rel...
  • Zhai19931004
  • Zhai19931004
  • 2016年05月09日 14:59
  • 3269
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:J2ME内存占用详解及优化方法
举报原因:
原因补充:

(最多只允许输入30个字)