众所周知,.NET Compact Framework 已经进入3.5时代,不过记得在2.0时代我写过一个利用回调方式EnumWindows的类。而且之前在写DeviceAnywhere的时候,实现过一个释放系统内存的功能。为什么要实现这个释放系统内存的功能呢?因为当初DeviceAnywhere的Phone端是常驻系统内存的,而且在系统内存过度消耗的情况下,会严重影响DeviceAnywherePhone的正常运行。
当初,为了实现这个释放系统内存的功能在Microsoft的线上MSDN找到一片关于Windows Mobile系统下WM_HIBERNATE消息的文章,而此消息正是实现释放系统内存的关键。文章告诉说,向每个窗口句柄发送WM_HIBERNATE消息,即是告诉其尽可能的降低内存消耗。所以,我们只要实现向windows mobile系统的每个窗口句柄发送该消息即可实现内存释放。
其实,当前很多主流的内存清理/释放程序均采用该方式进行内存释放。
在.net compact farmework 2.0以上环境下实现系统内存释放,我们只需要完成以下几个关键点即可达到目的:
1、获取系统当前运行程序的窗口句柄, 这里采取EnumWindows的方式
2、发送WM_HIBERNATE消息,这里我们采取SendMessage方式即可
3、读取系统当前有效物理内存,这里我们主要用来显示释放前后有效内存对比
4、SHCloseApps函数也可以一定程序的对应用程序内存进行释放
具体实现如下:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Optidiy.OptiApplication;
namespace Optidiy.OptiApplication
{
class OptiHibernate
{
public delegate int EnumWindowsProc(IntPtr hwnd, IntPtr lParam); //定义回调函数
public const int WM_HIBERNATE = 0x03FF; //定义消息的16进制代码
EnumWindowsProc callbackDelegate;//回调对象
IntPtr callbackDelegatePointer; //回调结果
[DllImport("coredll.dll")]//调用SendMessage函数
public static extern int SendMessage(IntPtr hWnd, uint Message, uint wParam, uint lParam);
[DllImport("coredll.dll", SetLastError = true)]//调用EnumWinows函数
public static extern bool EnumWindows(IntPtr lpEnumFunc, uint lParam);
[DllImport("aygshell.dll")]//调用SHCloaseApps函数
public static extern bool SHCloseApps(int dwMemSought);
[DllImport("coredll.dll")]//调用GlobalMemoryStatus获取内存状态函数
public static extern void GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer);
public struct MEMORYSTATUS
{
public int dwLength;
public int dwMemoryLoad;
public int dwTotalPhys;
public int dwAvailPhys;
public int dwTotalPageFile;
public int dwAvailPageFile;
public int dwTotalVirtual;
public int dwAvailVirtual;
}
//获取有效物理内存
public int GetAvailPhys()
{
MEMORYSTATUS memStatus = new MEMORYSTATUS();
GlobalMemoryStatus(ref memStatus);
return memStatus.dwAvailPhys;
}
//在构造函数中初始化遍历窗口对象
public OptiHibernate()
{
callbackDelegate = new EnumWindowsProc(EnumWindowsCallbackProc);
callbackDelegatePointer = Marshal.GetFunctionPointerForDelegate(callbackDelegate);
}
//在回调函数返回中发送内存释放消息
private int EnumWindowsCallbackProc(IntPtr hwnd, IntPtr lParam)
{
SendMessage(hwnd, WM_HIBERNATE, 0, 0);
return 1;
}
//进行窗口遍历
public void EnumWindows()
{
EnumWindows(callbackDelegatePointer, 0);
}
private const int MemSought = 1204 * 1024;
public bool FreeMemory()
{
return SHCloseApps(MemSought);
}
}
}
实例调用:
public void Hibernate()
{
OptiHibernate optiHibernate = new OptiHibernate();
int before = optiHibernate.GetAvailPhys();
optiHibernate.EnumWindows();
//formHandle为当前程序的句柄/为进行内存释放程序的句柄/调用该代码程序的句柄/主要实现自身的内存释放
OptiHibernate .SendMessage(formHandle, OptiHibernate.WM_HIBERNATE, 0, 0);
optiHibernate.FreeMemory();
int after = optiHibernate.GetAvailPhys();
MessageBox.Show("Before: " + before.ToString() + "/r" + "After: " + after.ToString(), "清理结果",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
}
注:该代码在vs.net2008 .net cf 3.5 windows mobile 5.0 SDK 下编译通过,Good Luck!
为Optidiy子功能之一!
转载请注明出处,谢谢!