内存管理 要精打细算

数字职场

内存管理,是软件开发的一个重点,在功能不变的情况下,如何有效地利用内存,减少资源的占用是衡量软件性能的重要指标之一。所以,很多公司在招聘时会侧重内存管理的考查。

招聘题目:下面的代码(Java)是否正确地释放了内存空间?为什么?

Image img[] = new Image[10];

for(int i = 0;i < 10;i++){

img[i] = Image.createImage("/img/" + i + ".png);

}

img = null; //释放内存

题目答案:该代码未释放全部内存,正确地释放全部内存的代码应该是:

Image img[] = new Image[10];

for(int i = 0;i < 10;i++){

img[i] = Image.createImage("/img/" + i + ".png);

}

//依次释放图片占用的内存

for(int i = 0;i < 10;i++){

img[i] = null;

}

img = null; //释放图片数组的内存

代码中,img=null仅仅释放了图片数组对象占用的内存,而每一个图片对象占用的内存没有被释放,所以如果需要释放全部内存,则要先释放每个图片对象占用的内存,再释放图片数组占用的内存,只有这样,才能达到正确释放内存的目的。

不可忽视内存占用

考官出这样的题目,目的是测试程序员是否有工作经验,是否对于内存管理有足够的认识。在软件开发中,内存管理不当轻则会导致工作效率低下,重则可能导致系统崩溃,所以内存管理的设计不能有疏忽。

在手机软件的开发中,因为手机内存不大,对内存管理的要求更加严格,有志于从事手机软件开发的朋友一定要多加注意,多实践,增加程序执行效率的体验,这样才可以在应聘者中脱颖而出。

实际应用

在实际的开发过程中,内存是怎么管理的?是如何提高执行速度和效率的?下面我们通过两组代码来进行说明。要求代码必须节约内存,第一组代码的效果不好。

代码1:

public void paint(Graphics g){

……

g.drawString("loading…",100,100,Graphics.TOP | Graphics.LEFT);

……

}

点评:该代码的功能是绘制字符串“loading…”,功能可以实现,但是系统每次绘制都需要生成一个字符串对象,比较浪费内存,而且每次都需要计算锚值,这将降低程序的执行效率。

代码2:

public void run(){

……

while(true){

int n = 10;

……

System.gc();

}

}

点评:在该代码中,在线程run中的循环,每次都生成一个int变量n,这样每次都需要为n分配内存,在循环结束时每次都得调用gc方法,效率低下。

第二组代码可以节约内存。

代码1:

public static final int TOPLEFT = Graphics.TOP | Graphics.LEFT; //避免重复计算

private String loadStr = "loading…"; //只生成一次字符串对象

public void paint(Graphics g){

……

g.drawString(loadStr,100,100,Graphics.TOP | Graphics.LEFT);

……

}

点评:通过声明TOPLEFT常数,避免重复计算,节约内存并提高程序的执行速度。通过声明loadStr对象,使字符串对象只在内存中生成一次,节约内存使用。

代码2:

public void run(){

……

int n = 10;

Runtime rt = Runtime.getRuntime();

while(true){

……

if(rt. freeMemory() < 102400){ //可用内存小于100K

System.gc();

}

}

}

点评:在循环中声明变量n,节约了内存的使用。在实际的开发中,很多人认为内存管理就是使用gc进行内存清理,其实良好的内存使用习惯才是最主要的,频繁地调用gc会显著降低程序的执行效率,所以正确的使用方法是当可用内存小于一定数值时,才调用gc方法进行内存的清理。