未连接监视器时 DWM 泄漏内存 Windows 8
DWM Leaks Memory When No Monitor Connected Windows 8
简单地说,如果没有连接显示器并且您正在 windows 8 嵌入式上执行一些 "windows" 操作,dwm.exe 开始分配内存,永不停止.
为了重新生成并向您展示所有问题,我编写了一个正在执行 "Create a new Form and show it, if there is one created close it first"
的应用程序
public partial class PopupWindows : Form
{
private Timer _t;
private Form _form;
public PopupWindows()
{
InitializeComponent();
this.Size = new Size(500, 500);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_t = new Timer();
_t.Tick += (o, ea) =>
{
_form?.Close();
(_form = new Form() { Size = this.Size }).Show();
};
_t.Interval = 1000;
_t.Enabled = true;
}
}
如果你运行这个应用程序并拔掉显示器,dwm开始分配页面
这是 pslist -m 当监视器连接时的输出
Name Pid VM WS Priv Priv Pk Faults NonP Page
dwm 840 123528 14400 11264 13044 55125 7 212
一段时间后,但 显示器仍处于连接状态
dwm 840 117144 15808 12732 13044 94051 7 200
正在断开监视器并且dwm.exe开始分配
dwm 840 214660 14444 12664 13044 137409 13 400
下面是输出,您可以在其中看到分配 dwm.exe 正在执行
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 251956 14460 12740 13044 137413 16 477
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 251956 14460 12740 13044 137413 16 477
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 251956 14460 12740 13044 137413 16 477
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 252964 14460 12740 13044 137413 16 479
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 252964 14460 12740 13044 137413 16 479
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 253972 14460 12744 13044 137413 16 481
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 253972 14460 12744 13044 137413 16 481
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 254980 14460 12744 13044 137413 16 483
dwm 的这种奇怪行为永远不会停止,直到您连接显示器或对计算机进行 vnc 连接。
在没有监视器的情况下运行一段时间后,每个os组件开始抱怨内存,最后出现蓝屏死机.
最后一张给大家看
dwm 840 807516 15624 14216 17240 147413 50 1603
这是显示我的 popupwindows.exe 运行ning
多少分钟的输出
Name Pid Pri Thd Hnd Priv CPU Time Elapsed Time
PopupWindows 2052 6 4 138 9468 0:00:00.140 0:23:07.332
如您所见,在设备上没有监视器的情况下大约 20 分钟后,dwm.exe 使用 807516 字节 VM 和 1603 页。
像 vnc 所做的那样(定期将整个屏幕位图复制到应用程序内存)解决了 dwm 的分配问题(我认为 dwm 缓存了它的输出,但没有人来要求更改,所以它把所有的都保存在内存,永远不会清理)。
下面是开始隐藏并定期将屏幕图像复制到应用程序内存中的应用程序
public partial class HiddenForm : Form
{
IntPtr _this;
private System.Windows.Forms.Timer _timer;
private Bitmap _bmp = null;
public HiddenForm()
{
this.Visible = false;
this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.None;
this.HandleCreated += (s, e) => _this = this.Handle;
this.Load += (s, e) => this.Size = new Size(0, 0);
CreateHandle();
CreateControl();
_timer = new System.Windows.Forms.Timer();
_timer.Tick += _timer_Tick;
_timer.Interval = 2000;
_timer.Start();
}
private void _timer_Tick(object sender, EventArgs e)
{
if (Screen.PrimaryScreen == null)
return;
if (_bmp == null)
{
using (Graphics g = CreateGraphics())
{
_bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, g);
}
}
using (Graphics grp = Graphics.FromImage(_bmp))
{
grp.CopyFromScreen(0, 0, 0, 0, _bmp.Size);
}
}
}
这是启动我的应用程序后的输出
Name Pid VM WS Priv Priv Pk Faults NonP Page
dwm 832 117876 20188 19624 35004 184497 7 185
正在使用 pskill 等待一段时间终止我的应用程序
dwm 832 182388 20264 19852 35004 421343 11 317
它开始增加以重新检查我们的应用程序我通过键入再次启动它
C:\HiddenForm.exe
和 dwm.exe 内存分配神奇地下降了。
dwm 832 126384 27900 27364 35144 556729 7 187
简单地说,如果没有连接显示器并且您正在 windows 8 嵌入式上执行一些 "windows" 操作,dwm.exe 开始分配内存,永不停止.
为了重新生成并向您展示所有问题,我编写了一个正在执行 "Create a new Form and show it, if there is one created close it first"
的应用程序public partial class PopupWindows : Form
{
private Timer _t;
private Form _form;
public PopupWindows()
{
InitializeComponent();
this.Size = new Size(500, 500);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_t = new Timer();
_t.Tick += (o, ea) =>
{
_form?.Close();
(_form = new Form() { Size = this.Size }).Show();
};
_t.Interval = 1000;
_t.Enabled = true;
}
}
如果你运行这个应用程序并拔掉显示器,dwm开始分配页面 这是 pslist -m 当监视器连接时的输出
Name Pid VM WS Priv Priv Pk Faults NonP Page
dwm 840 123528 14400 11264 13044 55125 7 212
一段时间后,但 显示器仍处于连接状态
dwm 840 117144 15808 12732 13044 94051 7 200
正在断开监视器并且dwm.exe开始分配
dwm 840 214660 14444 12664 13044 137409 13 400
下面是输出,您可以在其中看到分配 dwm.exe 正在执行
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 251956 14460 12740 13044 137413 16 477
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 251956 14460 12740 13044 137413 16 477
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 251956 14460 12740 13044 137413 16 477
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 252964 14460 12740 13044 137413 16 479
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 252964 14460 12740 13044 137413 16 479
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 253972 14460 12744 13044 137413 16 481
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 253972 14460 12744 13044 137413 16 481
C:\PSTools>pslist.exe -m|findstr "dwm"
dwm 840 254980 14460 12744 13044 137413 16 483
dwm 的这种奇怪行为永远不会停止,直到您连接显示器或对计算机进行 vnc 连接。
在没有监视器的情况下运行一段时间后,每个os组件开始抱怨内存,最后出现蓝屏死机.
最后一张给大家看
dwm 840 807516 15624 14216 17240 147413 50 1603
这是显示我的 popupwindows.exe 运行ning
多少分钟的输出Name Pid Pri Thd Hnd Priv CPU Time Elapsed Time
PopupWindows 2052 6 4 138 9468 0:00:00.140 0:23:07.332
如您所见,在设备上没有监视器的情况下大约 20 分钟后,dwm.exe 使用 807516 字节 VM 和 1603 页。
像 vnc 所做的那样(定期将整个屏幕位图复制到应用程序内存)解决了 dwm 的分配问题(我认为 dwm 缓存了它的输出,但没有人来要求更改,所以它把所有的都保存在内存,永远不会清理)。
下面是开始隐藏并定期将屏幕图像复制到应用程序内存中的应用程序
public partial class HiddenForm : Form
{
IntPtr _this;
private System.Windows.Forms.Timer _timer;
private Bitmap _bmp = null;
public HiddenForm()
{
this.Visible = false;
this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.None;
this.HandleCreated += (s, e) => _this = this.Handle;
this.Load += (s, e) => this.Size = new Size(0, 0);
CreateHandle();
CreateControl();
_timer = new System.Windows.Forms.Timer();
_timer.Tick += _timer_Tick;
_timer.Interval = 2000;
_timer.Start();
}
private void _timer_Tick(object sender, EventArgs e)
{
if (Screen.PrimaryScreen == null)
return;
if (_bmp == null)
{
using (Graphics g = CreateGraphics())
{
_bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, g);
}
}
using (Graphics grp = Graphics.FromImage(_bmp))
{
grp.CopyFromScreen(0, 0, 0, 0, _bmp.Size);
}
}
}
这是启动我的应用程序后的输出
Name Pid VM WS Priv Priv Pk Faults NonP Page
dwm 832 117876 20188 19624 35004 184497 7 185
正在使用 pskill 等待一段时间终止我的应用程序
dwm 832 182388 20264 19852 35004 421343 11 317
它开始增加以重新检查我们的应用程序我通过键入再次启动它
C:\HiddenForm.exe
和 dwm.exe 内存分配神奇地下降了。
dwm 832 126384 27900 27364 35144 556729 7 187