Windows 窗体内存泄漏

2024-01-08

我在 Windows 应用程序中发现轻微的内存泄漏。我在我的应用程序中使用 DevExpress XtraForm。我看到的是该表格的一个实例始终保存在内存中。如果您多次打开同一个表单,它仍然保留上次打开的表单的引用。

前任。如果您在应用程序中打开 10 个不同的表单并关闭所有它们,它仍然不会释放分配给它的内存,因为一些奇怪的“MdiClient 对象引用 LayoutEventArgs 对象”。幸运的是,它保留了每种类型的单个项目的引用。

以下是 Redgate 内存分析器输出的链接。

https://dl.dropboxusercontent.com/u/2781659/Memory%20Leak.pdf https://dl.dropboxusercontent.com/u/2781659/Memory%20Leak.pdf

在上面的图表中,DepartmentsForm 已被处置,但无法被 GC,因为 LayoutEventArgs 的affectedComponent 成员引用了它。

如果您发现任何明显错误,请指出。


根据我的经验,在 Windows 窗体中,在某些情况下,可以将已释放的控件缓存在LayoutEventArgs对象,它看起来像是 WinForms 中的某种小错误。

一些细节:
每个实例的System.Windows.Forms.Controltype 包含一个私有成员变量LayoutEventArgstype - cachedLayoutEventArgs。并且,LayoutEventArgs通常包含对某些特定控件的引用。您可以通过 Reflector 清楚地看到所有这些事实。并且,有时,cachedLayoutEventArgs由于某些原因,子控件处置时未清除字段不影响父控件的布局过程。您可以使用 mdi 父窗体来模拟这种情况,方法是在关闭其子级时暂停 MdiClient 的控件布局:

public partial class MdiParentForm : Form {
    public MdiParentForm () {
        InitializeComponent(); //  this.IsMdiContainer = true
    }
    void buttonAddMdiChild_Click(object sender, EventArgs e) {
        MdiChildForm f = new MdiChildForm();
        f.MdiParent = this;
        f.Show();
    }
    void buttonCloseMdiChild_Click(object sender, EventArgs e) {
        MdiClient client = GetMdiClient(this);
        client.SuspendLayout();

        if(ActiveMdiChild != null)
            ActiveMdiChild.Close();

        client.ResumeLayout(false); 
        // !!! At this point the MdiClient.cachedLayoutEventArgs contains the reference to disposed control (leak)
    }
    static MdiClient GetMdiClient(Form frm) {
        if(frm != null) {
            foreach(Control ctrl in frm.Controls) {
                if(ctrl is MdiClient)
                    return (MdiClient)ctrl;
            }
        }
        return null;
    }
}
class MdiChildForm : Form { }

有一个简单的解决方法 - 通过触发PerformLayout方法,您可以有效地清除该“缓存”实例:

class MdiChildForm : Form {
    MdiClient parent;
    protected override void OnParentChanged(EventArgs e) {
        base.OnParentChanged(e);
        var mdiClient = Parent as MdiClient;
        if(mdiClient != parent) {
            if(parent != null)
                parent.PerformLayout();
            parent = mdiClient;
        }
    }
}

附:无论如何,我建议您联系DevExpress 支持 https://www.devexpress.com/Support/Center/对此,确认你所描述的内存泄漏与其控件无关并得到最终的解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows 窗体内存泄漏 的相关文章

  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 为什么禁止在 constexpr 函数中使用 goto?

    C 14 对你能做什么和不能做什么有规则constexpr功能 其中一些 没有asm 没有静态变量 看起来相当合理 但标准也不允许goto in constexpr功能 即使它允许其他控制流机制 这种区别背后的原因是什么 我以为我们已经过去
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 基于范围的 for 循环中的未命名循环变量?

    有没有什么方法可以不在基于范围的 for 循环中 使用 循环变量 同时也避免编译器发出有关未使用它的警告 对于上下文 我正在尝试执行以下操作 我启用了 将警告视为错误 并且我不想进行像通过在某处毫无意义地提及变量来强制 使用 变量这样的黑客
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • 使用安全函数在 C 中将字符串添加到字符串

    我想将文件名复制到字符串并附加 cpt 但我无法使用安全函数 strcat s 来做到这一点 错误 字符串不是空终止的 我确实设置了 0 如何使用安全函数修复此问题 size strlen locatie size nieuw char m
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 初始化变量的不同方式

    在 C 中初始化变量有多种方法 int z 3 与 int 相同z 3 Is int z z 3 same as int z z 3 您可以使用 int z z 3 Or just int z 3 Or int z 3 Or int z i
  • 用 C 实现 Unix shell:检查文件是否可执行

    我正在努力用 C 语言实现 Unix shell 目前正在处理相对路径的问题 特别是在输入命令时 现在 我每次都必须输入可执行文件的完整路径 而我宁愿简单地输入 ls 或 cat 我已经设法获取 PATH 环境变量 我的想法是在 字符处拆分
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 将应用程序从 Microsoft Access 迁移到 VB 或 C#.NET

    我目前正试图说服管理层需要将我们的应用程序之一移植到 NET 该应用程序已经发展成为 Access 中的一个庞然大物 SQL 后端 拥有 700 个链接表 650 个表单 子表单 130 个模块和 850 个查询 我几乎知道这样做的所有主要
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的
  • 为什么 strtok 会导致分段错误?

    为什么下面的代码给出了Seg 最后一行有问题吗 char m ReadName printf nRead String s n m Writes OK char token token strtok m 如前所述 读取字符串打印没有问题 但
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束

随机推荐

  • 使用 TPL 时如何在 UI 线程上调用方法?

    我正在开发一个 MVVM 应用程序 它使用 TPL 在后台执行多项任务 任务需要向 UI 报告进度 以便可以更新进度对话框 由于应用程序是 MVVM 因此进度对话框绑定到名为 Progress 的视图模型属性 该属性由具有签名的视图模型方法
  • JavaFX 拖放到 GridPane?

    我已经为我的游戏实现了拖放功能 但到目前为止我只能 拖放到 硬编码的位置 如图所示 我想要的是 当船舶被放下时 它的 x y 值 相对于 GridPane 被保存 或者 飞船掉落到的单元格被保存 我的 setOnDragDropped 事件
  • Jenkins gerrit 触发器在构建时未获取我的更改

    我已经使用 gerrit 触发器插件配置了 jenkins 以验证我们推送到 gerrit 的每个提交 我希望这个触发器包含我对原始存储库的最新更改并进行构建 但是 它仅克隆回购项目并进行编译 而无需我进行更改 以下是我在詹金斯中对 ger
  • 如何运行快照插件

    当我尝试使用以下命令运行下面的 Maven 插件时 com wordpress pomfromjarmavenplugin generate 0 0 1 SNAPSHOT generatepom 我收到此错误 下载中 https oss s
  • 如果数字以 1 结尾做某事

    我想做这样的事情 if day 1 day 11 day 21 day 31 day 41 result dan else result dana 我怎样才能对每个以 1 结尾的数字做到这一点 当然又不写出所有数字 只需检查除以 10 的余
  • 始终使用 Serilog 记录上下文数据

    我正在使用 Serilog 进行日志记录 对于每个日志 我想记录上下文信息 例如用户名和其他一些上下文信息 所以我用静态方法创建了包装器 如下所示 public static class MyLogger public static voi
  • Windows .cmd 标准输出 - 多重重定向

    给定一个 windows cmd 文件abc cmd abc cmd gt output log 上述命令行操作会将执行的输出保存到output log 文件中 是否有选项可以运行此命令以创建此日志的多个副本 也就是说 我希望在一个位置创建
  • highcharts 不尊重我的 x 轴日期间隔

    几周以来 我每 15 分钟收集一次一系列数据 不幸的是 中间有一个星期的数据缺失 这只是我的一个事实 当我使用 Highcharts 绘制这些数据的图表时 它会压缩 x 轴 时间 从而使图表倾斜 例如 x 轴每 2 小时就有一次主要刻度 直
  • 代码中的注释页眉和页脚真的有必要吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • C++ 构造函数初始化列表中的 vim 缩进

    include
  • 让 Gmail 自动显示我嵌入 HTML 电子邮件中的图像?

    我正在使用 Zend Mail 在 PHP 中构建 HTML 电子邮件 并且我想嵌入 附加 任何图像 以便 Gmail 会自动显示它们而不提示用户 我怎样才能做到这一点 谷歌的假设 Gmail 将自动为已验证其域的发件人显示图像 为确保 G
  • java.lang.IllegalStateException:查询 GraphQL 后递归更新

    我正在查询 graphQL 但遇到了这个异常 java lang IllegalStateException Recursive update at java base java util concurrent ConcurrentHash
  • tkinter Checkbutton 小部件返回错误的布尔值

    我这里有一个简单的 GUI 它应该根据检查按钮是否被选中返回一个布尔值 我已将布尔变量设置为 False 因此检查按钮为空 我不明白的是 当我检查按钮时 绑定到该小部件的函数返回 False 而不是 True 这是为什么 这是代码 from
  • Swift:对 NSNotFound 的引用不明确

    在向某些 Objective C 代码添加桥接标头后 我开始收到有关以下内容的编译器错误 NSNotFound是一个不明确的参考 我的猜测是它可以用某种模块前缀来修复 是的 将其更改为 Foundation NSNotFound
  • 如何在 Android SeekBar 上添加数字刻度

    我正在使用开箱即用的 android SeekBar 组件 下面我想添加 1 到 5 中的数字来显示 SeekBar 的进度 我在搜索栏上正确分配数字时遇到问题 就像下图一样 要在搜索栏拇指上绘制文本 请使用此功能 public Bitma
  • Rails 中用户注销后如何使所有会话失效?

    我是 Rails 新手 并且正在关注 Michael Hartl 的 Rails 教程 因此我的代码大部分是从那里借来的 这是场景 我使用以下方式登录我的网站Computer A 然后我使用相同的用户 ID 登录该网站Computer B
  • Android 文件路径 (Xamarin)

    我目前正在尝试选择一个具有意图的文件 我的问题是 返回的路径格式不正确 我的意图 private void selectAudioFile object sender EventArgs eventArgs Intent new Inten
  • PDF:提取的图像被切片/平铺

    图像提取pdfimages and mupdf mutool到目前为止工作正常 使用 FreePDF 生成的 PDF 中的图像始终会被切片 因此一张图像会生成多个图像文件 有什么技巧可以避免这种情况吗 我如何使用结果pdfshow 有没有坐
  • Lucene 索引

    我想使用 Lucene 为现有数据库中的表建立索引 我一直在想这个过程是这样的 为表中的每一列创建一个 字段 存储所有字段 分析 除具有主键的字段之外的所有字段 将表中的每一行存储为 Lucene 文档 虽然此表中的大多数列都很小 但其中有
  • Windows 窗体内存泄漏

    我在 Windows 应用程序中发现轻微的内存泄漏 我在我的应用程序中使用 DevExpress XtraForm 我看到的是该表格的一个实例始终保存在内存中 如果您多次打开同一个表单 它仍然保留上次打开的表单的引用 前任 如果您在应用程序