LabVIEW
程序的内存优化
一. VI 在内存中的结构
打开一个
VI
的属性面板(
VI Properties
),其中的
“
内存使用
”
(
Memory Usage
)是用来查看
这个
VI
内存占用情况的。它显示了一个
VI
内存占用所包含的四个主要部分:前面板、框图、代码和
数据,以及这四个部分的总和。但在打开一个
VI
时,这四段内容并不是同时都会被
LabVIEW
调入
内存的。
当我们打开一个主
VI
时,主
VI
连同它的所有子
VI
的代码和数据段都会被调入内存。由于主
VI
的前面板一般情况下是打开的,它的前面板也就同时被调入内存。但是此时主
VI
的框图和子
VI
的前
面板、框图并没有被调入内存。只有当主动查看主
VI
的框图或是打开子
VI
的前面板和框图时,它们
才会被调入。
基于
LabVIEW
的这种内存管理的特性,我们在编写
VI
的时候可以通过以下方法来优化
LabVIEW
程序的内存使用。
第一,把一个复杂
VI
分解为数个子
VI
。子
VI
的使用会增添额外的前面板和框图的空间,但并不
增添额外的代码和数据空间。由于程序运行时只有代码和数据被调入内存,因此使用子
VI
不会占用
额外的内存。使用子
VI
的好处还在于当子
VI
运行结束时,
LabVIEW
可以及时收回子
VI
的数据空
间,从而改善了内存的使用效率。
第二,在没有必要时不要设置子
VI
的重入(
Reentrant
)属性。重入型
VI
每次运行时都会对自
己使用的数据生成一个副本,这增加了内存开销。
第三,主
VI
的面板通常就是用户界面,需要显示给用户。但是要尽量避免开启子
VI
前面板。比
如,在子
VI
中使用与其前面板控件有关的属性节点(
Property Node
)会导致它的前面板被调入内
存中,增加了内存开销,所以要尽量避免在子
VI
中使用主面板控件的属性节点来设置控件的值,而
可以用局部变量等方法来替代。
第四,我们可以放心地在
VI
的前面板(对于非界面
VI
)和框图里添加图片,注释等信息来帮助你
编写、维护
LabVIEW
程序,这些帮助信息不会在
VI
运行时占用内存。
二
.
内存泄漏
LabVIEW
与
C
语言不同,它没有任何分配或释放内存的语句,
LabVIEW
可以自动管理内存,在
适当的时候分配或收回内存资源
[1]
。这样就避免了
C
语言中常见的因为内存管理语句使用不当而引
起的内存泄漏。
在
LabVIEW
中一般只有一种情况能够引起内存泄漏,即你打开了某些资源,却忘记了关闭它们。
比如,在对文件操作时,我们需要先打开这个文件,返回它的句柄。随后如果忘记了关闭这个句柄,
它所占用的内存就始终不会被释放,从而产生内存泄漏。
LabVIEW
中其它带有打开句柄的函数或
VI
也会引起同样的问题。
由于内存泄漏是动态产生的,我们无法通过
VI
的属性面板来查看,但可以通过
Windows
自带的
任务管理工具来查看
LabVIEW
程序内存是否有泄漏。也可以使用
LabVIEW
的
Profile
(Tools>>Advanced>>Profile VIs)
工具来查看某个
VI
运行时内存的分配情况。
三
.
缓存重用
LabVIEW
程序主要是数据流驱动型的。数据传递到不同节点时往往需要复制一个副本。这是
LabVIEW
为了防止数据被节点改变引起错误所做的一种数据保护措施。只有当目标节点为只读节点,
不可能对输入数据作任何更改时,才不在这些节点处做备份。
例
如,数
组索
引节点(
Index
)是不会
改变数
组
值的,
LabVIEW
在这里就不为输入数
组
做备份。对于加
减
法运
算
等
肯定
改变输入数据的节
点,
LabVIEW
往往需要对输入或输
出
数据作备份。有些
LabVIEW
程序,比如
涉
及到
大
数
组
运
算
的
程序,内存
消耗极大
。其主要
原
因就是
LabVIEW
在运
算
时为数
组
数据生成了过
多
的副本。
实际上很多
LabVIEW
节点是
允许
使用
缓
存重用的,这
类似
C
语言调用子函数所使用的地
址
传递。