您的位置:首页 > 编程语言 > C#

.NET Compact Framework 2.0以上用c#实现windows mobile 系统内存释放

2010-06-15 23:48 393 查看
众所周知,.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子功能之一!

转载请注明出处,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: