首页 > 系统相关 >5.4节约内存的编程方式

5.4节约内存的编程方式

时间:2023-02-05 11:23:28浏览次数:37  
标签:文件 5.4 函数 Windows 编程 DLL 内存 应用

以图形用户界面(GUI, Graphical User Interface)为基础的Windows,可以说是一个巨大的操作系统。Windows的前身是MS-DOS操作系统,最初版本可以在128KB左右的内存上运行,而想要Windows流畅运行的话,至少需要512MB的内存。而且,由于Windows具有多任务功能,在巨大的Windows操作系统中可以同时运行多个应用,因此,即使是512MB的内存,有时也无法保证流畅运行。Windows操作系统经常为内存不足所困。
像Windows这样,窗口的菜单及图表等都可以进行可视化操作的方式称为图形用户界面。Windows的前身MS-DOS操作系统,是由键盘输入命令来进行操作的CLI(命令行界面)。

 许多人可能会认为,通过借助磁盘虚拟内存就可以解决内存不足的问题。而虚拟内存也确实能避免因内存不足导致的应用无法启动。不过,由于使用虚拟内存时发生的Page In和Page Out往往伴随着低速的磁盘访问,因此在这个过程中应用的运行会变得迟钝起来。想必大家也都有过在操作应用的过程中硬盘访问灯一直亮着(这时正在进行Page In和Page Out),导致应用一时无法操作的不愉快经历吧。也就是说,虚拟内存无法彻底解决内存不足的问题。

为了从根本上解决内存不足的问题,需要增加内存的容量,或者尽量把运行的应用文件变小。接下来会向大家介绍两个把应用文件变小的编程方法。虽然增加内存容量更为便捷,但是花费也高。

(1)通过DLL文件实现函数共有

DLL文件:是在程序运行时可以动态加载Library(函数和数据的集合)的文件。此外,还有一个需要大家注意的地方,那就是多个应用可以共有同一个DLL文件。而通过共有同一个DLL文件则可以达到节约内存的效果。
例如,假设我们编写了一个具有某些处理功能的函数MyFunc()。应用A和应用B都会使用这个函数。在各个应用的运行文件中内置函数 MyFunc()(这个称为Static Link,静态链接)后同时运行这两个应用,内存中就存在了具有同一函数的两个程序。但这会导致内存的利用效率降低。所以,有两个同样的函数,还是有点浪费,如下图:

 由于同一个DLL文件的内容在运行时可以被多个应用共有,因此内存中存在函数MyFunc()的程序就只有1个。这样一来,内存的利用效率也就提高了。

 Windows中,可以执行的应用文件的扩展名是.exe,这样的文件就称为EXE文件。exe是executable(可执行)的略写。另一方面,DLL文件的扩展名为.dll。

Windows的操作系统本身也是多个DLL文件的集合体。有时在安装新应用时,DLL文件也会被追加。应用则会通过利用这些DLL文件的功能来运行。像这样,之所以要利用多个DLL文件,其中一个原因就是可以节约内存。而且DLL文件还有一个优点就是,在不变更EXE文件的情况下,只通过升级DLL文件就可以更新。

(2)通过调用_stdcall来减小程序文件的大小
通过调用_stdcall”来减小程序文件的方法,是用C语言编写应用时可以利用的高级技巧。不过,这一思路应该也可以应用在其他编程语言中。
_stdcall是standard call(标准调用)的略称。Windwos提供的DLL文件内的函数,基本上都是_stdcall调用方式。这主要是为了节约内存。另一方面,用C语言编写的程序内的函数,默认设置都不是_stdcall。C语言特有的调用方式称为C调用。C语言之所以默认不使用_stdcall,是因为C语言所对应的函数的传入参数是可变的(可以设定任意参数),只有函数调用方才能知道到底有多少个参数,而这种情况下,栈的清理作业便无法进行。不过,在C语言中,如果函数的参数数量固定的话,指定_stdeall是没有任何问题的。

C语言中,在调用函数后,需要执行栈清理处理指令。

栈清理处理是指把不需要的数据从接收和传递函数的参数时使用的内存上的栈区域中清理出去。该命令不是程序记述的,而是在程序编译时由编译器自动附加到程序中的。编译器默认将该处理附加在函数调用方。

例如,在代码清单5-1中,从函数 main(中调用了函数 MyFunc0。按照默认设定,栈的清理处理会附加在函数main)这一方。在同一个程序中,同样的函数可能会被多次反复调用。而如果是同样的函数,栈清理处理的内容也是一样的。由于该处理是在调用函数一方,因此就会导致同一处理被反复进行。这就造成了内存的浪费。

 虽然通过调查编译器生成的机器语言执行文件就可以得知栈清理的处理内容,不过鉴于原始的机器语言不太容易理解,所以这里我们用汇编语言的代码清单将其显示了出来。将代码清单5-1中调用函数MyFunc()的部分用汇编语言来表示,就如代码清单5-2所示。最后1行的处理就是清理处理。

 C的3个字节)的程序大小,不过在整个程序中还是有效果的(图5-7)。

 

标签:文件,5.4,函数,Windows,编程,DLL,内存,应用
From: https://www.cnblogs.com/z1218/p/17093055.html

相关文章

  • 内存和磁盘的亲密关系——5.1不读入内存就无法运行
    1.存储程序方式指的是什么?在存储装置中保存程序,并逐一运行的方式2.通过使用内存来提高磁盘访问速度的机制称为什么?DiskCache(磁盘缓存)3.把磁盘的一部分作为假想内存来......
  • 5.3虚拟内存把磁盘作为部分内存来使用
    接下来说一下虚拟内存虚拟内存是指把磁盘的一部分作为假想的内存来使用。这与磁盘缓存是假想的磁盘(实际上是内存)相对,虚拟内存是假想的内存(实际上是磁盘)。通过借助虚拟......
  • 熟练使用有棱有角的内存——4.1内存的物理机制很简单
    1.有十个地址信号引脚的内存IC(集成电路)可以指定的地址范围是多少?答:用二进制数来表示的话是0000000000~1111111111(用十进制数来表示的话是0~1023)2.高级编程语言中的数......
  • 4.2内存的逻辑模型是楼房
    虽然内存的实体是内存IC,不过从程序员的角度来看,也可以把它假想成每层都存储着数据的楼房,并不需要过多地关注内存IC的电源和控制信号等。因此,之后的讲解中我们也同样会使用......
  • 4.4数组是高效使用内存的基础
    数组是指多个同样数据类型的数据在内存中连续排列的形式。作为数组元素的各个数据会通过连续的编号被区分开来,这个编号称为索引(index)。指定索引后,就可以对该索引所对应地......
  • 【C++ 泛型编程01:模板】函数模板与类模板
    【模板】除了OOP外,C++另一种编程思想称为泛型编程,主要利用的技术就是模板C++提供两种模板机制:函数模板和类模板函数模板函数模板作用建立一个通用函数,其函数......
  • C语言学习: 结构体的内存对齐
    怎么对齐的?是对齐他占用内存的倍数,看下面的代码intmain(){typedefstructPerson{char*name;intage;char*id;}Person;structPerson......
  • 06 创建对象内存分析
    现在不太懂什么是栈,什么是堆?无关代码,个人此时喜好记录packagecom.zhan.base05Oop;publicclassTest06{publicstaticvoidmain(String[]args){P......
  • Go应用服务疑似内存泄露问题排查
    背景为了保障业务的可用性,增加应用服务请求依赖服务(grpc、http)的熔断降级策略,避免依赖服务不可用的情况下,出现级联服务故障产生雪崩,通过熔断降级尽可能把影响缩放到最小。因......
  • 论文阅读: CCF A(ICSE) 2022 MVD: 基于流敏感图神经网络的内存相关漏洞检测
    Abstract:内存相关漏洞对现代软件的安全构成了严重威胁。尽管基于深度学习的方法在一般性漏洞检测方面取得了成功,但在应用于内存相关漏洞检测时,仍然受到流信息利用不......