}
解决:C语言中malloc和free函数要配对使用。
void foo()
{
//定义string1指针,其指向一个堆上的100个字节的内存空间
char *string1 = (char*)malloc(100*sizeof(char));
//定义string2指针,其指向一个堆上的200个字节的内存空间
char *string2 = (char*)malloc(200*sizeof(char));
scanf("%s", string2);
string1=string2;/*string1原先指向的100个字节的内存没有被释放*/
/*而后又被指向string2所指的内存块,造成前面100个字节的内存泄漏*/
free(string2);
free(string1); /* 这个free()调用会失败,因为string1指向的内存地址与string2的相同,而那块内存已经被释放了 */
return 0;
}
解决:在程序堆上分配内存后,要在使用完后及时释放,同时避免野指针的产生,比如string1。
原理:内存是软件运行的重要的空间资源,内存泄漏实际上是浪费了软件的空间资源。因此,内存泄漏对软件的性能影响十分重要。
另外,对于程序在时间上的浪费,我们通常是采用优化算法和数据结构的解决策略。
最近几年,很多知名软件公司在招聘软件测试人员,考察代码能力的时候,内存泄露和算法优化是经常的试题之一。这说明了用户对软件性能的要求越来越严格,已经传递到了软件公司。
2.以空间换时间
软件的高性能并不是凭空产生的,在解决了空间和时间浪费的问题之后,如果用户还有更高的性能要求,我们软件人员只好“偷梁换柱”,做一下调整,而这种调整往往是很灵活的。
空间换时间是软件人员解决性能问题最常见的方法。是在系统功能正常的前提下增大软件空间开销的方法来缩减运行的时间。一般的方法有算法调整、并行计算方法、体系结构方法和一些不是“办法”的办法。
通常的解决方案有Cache缓存、数据库的index等。
一个动态网站服务器总发生CPU耗尽的问题,因此造成给用户的响应缓慢或者长时间没有响应,进而引起Server的宕机。经调查分析,网站首页是个PHP 程序,每次用户访问都要多次查询数据库,也没有Cache机制,数据库查询负荷过高,耗尽CPU。
解决:改写网站首页以及部分频繁访问的程序,增加Cache机制,减少数据库访问。
原理:将常用数据放在服务器的内存中,虽然增加了内存的开销,但带来了时间上的优化,对用户而言,提高了处理速度。
3.以时间换空间
时间换空间的方案解决性能问题的情形比较少。有时会出现在对内存要求十分苛刻的地方,比如嵌入式操作系统中。
程序设计的要求是不设中间变量,交换两个变量的值。
我们通常的中间变量的解决方案是:
Void swapOne(int *a, int *b)
{
Int temp;
Temp = *a;
*a = *b;
*b= temp;
}
但这里需要在程序中为temp变量在栈上分配一个空间。可不可以不用这个temp变量呢?
解决:
修改程序如下:
void swapTwo(int *a,int *b)
{
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
}
原理:修改之后,多了运算复杂度,但没有使用第三方变量,减少了空间的占用。
以上是我们从简单的程序例子来理解性能解决方案,但现实要远远复杂得多,因为随着软件系统功能的复杂强大,软件的规模也在不断扩大,我们不可能完全自己开发程序,很多时候是利用已有的平台和中间件资源。在这种场景下,我们应该怎样考虑性能问题呢?
第一,软件系统设计的架构及技术平台
软件在设计阶段一旦决定采用哪种架构和技术,其性能也就注定只能在一定的范围内变动了。这就是“先天”因素。比如在上节讲到的一个删除/增加数据的业务操作,如果用户对时间非常苛刻,密集型计算、在线的大数据量统计和分析等应用,这些场景通常J2EE不能够很好地解决,使用C++或者其他平台搭建会更合理些。如果在这些场景下硬要采用J2EE架构,那么开发和设计人员如何绞尽脑汁,优化设计和程序,也不会满足用户的性能要求。