【问题标题】:DWM Leaks Memory When No Monitor Connected Windows 8未连接显示器时 DWM 泄漏内存 Windows 8
【发布时间】:2019-02-07 11:31:13
【问题描述】:

简单地说,如果没有连接显示器并且您正在嵌入式 Windows 8 上执行一些“windows”操作,dwm.exe 开始分配内存并且永不停止。

为了重新生成并向您展示所有问题,我编写了一个应用程序,该应用程序正在执行“创建一个新表单并显示它,如果创建了一个则先关闭它”

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 连接到计算机。

无显示器运行一段时间后,每个操作系统组件开始抱怨内存,最后出现蓝屏死机。

让我给你看最后一张

dwm                 840  807516   15624   14216   17240   147413     50 1603

这是显示我的 popupwindows.exe 运行了多少分钟的输出

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 个页面。

【问题讨论】:

    标签: windows memory-leaks dwm bsod


    【解决方案1】:

    像 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 2013-01-11
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      相关资源
      最近更新 更多