[编程]如何减少.Net应用程序启动时占用的内存 [2007-04-02 更新]

现象描述:
在运行.Net编写的Windows窗体应用程序时,会发现一个有趣的现象:
那就是应用程序占用的内存往往超过10M——至少使用VB.Net编写的应用程序是这样的。
哪怕是运行默认生成的窗体,哪怕是一行代码也不添加,也会在任务管理器中占有超过10M的内存。

是否真的吃掉了这么多内存?
请将窗体应用程序最小化再查看占用内存——往往会降低到1M左右,这就比较理想了。
即使再次恢复大小,占用内存仍然不高。

原因何在?
我不知道,也许启动时占用内存是因为需要调用dotnet framework吧。

那最小化时发生了什么?
仍然不知道,也许是dotnet的自动垃圾收集起作用了,也许仅仅是将东西转入了虚拟内存。

如何利用这一特点帮助(至少表面上)减少应用程序占用的内存?
可以通过在启动时强迫窗体最小化来达成愿望,事实证明这是奏效的。

代码举例说明?
下列VB.Net 2005代码片断通过窗体变量m_IsHide来控制是否将窗体最小化并隐藏,初始化为True。
为了运行下列代码,还需要一个NotifyIcon及一个与之关联的ContextMenuStrip,后者包含mnuShow和mnuHide菜单两枚。

Private  m_IsHide  As   Boolean   =   True

Private   Sub frmMain_Activated(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Activated
    
If m_IsHide Then
        
Me.WindowState = FormWindowState.Minimized
        
Me.Hide()
    
Else
        
Me.WindowState = FormWindowState.Normal
        
Me.Show()
    
End If
End Sub


Private   Sub frmMain_Resize(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Resize
    
If Me.WindowState = FormWindowState.Minimized Then
        m_IsHide 
= True
        
Me.Hide()
    
End If
End Sub


Private   Sub mnuShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuShow.Click
    m_IsHide 
= False

    
Me.WindowState = FormWindowState.Normal
    
Me.Show()
End Sub


Private   Sub mnuHide_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuHide.Click
    m_IsHide 
= True

    
Me.WindowState = FormWindowState.Minimized
    
Me.Hide()
End Sub

上述代码的功能是:
1、 启动时最小化并隐藏
2、 点击mnuHide窗体隐藏
3、 点击mnuShow窗体恢复
4、 最小化时窗体隐藏

总结一个:
一句话,其实就是编程使窗体启动时最小化。 


2007-04-02 更新

今日搜资料,找到了原因,确认是Windows将程序占用的内存倒入虚拟内存可以造成小内存占用的假象。

乐天居上有篇文章“ 将物理内存的占用挪到虚拟内存里-----揭密篇 ”对此有完整的介绍:“ 而是操作系统本身就有这个机制,即当程序不使用时(最小化),操作系统会调用某些命令,来将该程序占用的内存移至虚拟内存,只保留一小部分常规代码

BOOL SetProcessWorkingSetSize(
  HANDLE hProcess ,
  SIZE_T dwMinimumWorkingSetSize ,
  SIZE_T dwMaximumWorkingSetSize
);

将 2个  SIZE_T  参数设置为 -1 ,即可以使进程使用的内存交换到虚拟内存,只保留一小部分代码。

事实上,使用该函数并不能提高什么性能,也不会真的节省内存。因为他只是暂时的将应用程序占用的内存移至虚拟内存,一旦,应用程序被激活或者有操作请求时,这些内存又会被重新占用。如果你强制使用该方法来 设置程序占用的内存,那么可能在一定程度上反而会降低系统性能,因为系统需要频繁的进行内存和硬盘间的页面交换。

给出我在VB2005中的使用范例:

Imports  System.Runtime.InteropServices

Module modMain
    
<DllImport("kernel32.dll")> _
    
Public Function SetProcessWorkingSetSize( _
        
ByVal hProcess As Integer, _
        
ByVal dwMinimumWorkingSetSize As Integer, _
        
ByVal dwMaximumWorkingSetSize As Integer) _
        
As Integer

    
End Function


    
<DllImport("kernel32.dll")> _
    
Public Function GetCurrentProcess() As Integer
    
End Function


    
Public Sub ReduceMem()
        SetProcessWorkingSetSize(GetCurrentProcess, 
-1-1)
    
End Sub

End Module

使用ReduceMem()函数的效果很赞,但是不建议经常用,我只是在FormLoad时用一下,效果就很好了。
值得一提的是,如果不使用GetCurrentProcess()函数得到当前Process,而是使用Process.GetCurrentProcess(),则无法有效缩减使用内存。
原因不详。

总结:建议使用ReduceMem()来减少表面占用内存,忘掉上面启动时最小化的方法吧……

再次感谢乐天居的文章。 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值