首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >减少内存消耗的方法WPF应用程序

减少内存消耗的方法WPF应用程序
EN

Stack Overflow用户
提问于 2022-10-31 15:39:06
回答 1查看 65关注 0票数 -3

日安。

我创建了一个小程序来创建调色板。没事的,它正常工作。程序截图

整个代码是这里。发行版是这里

所创建的纹理作为一种材料用于三维建模。程序的工作方式如下:

  1. 用户选择颜色范围和色调。
  2. 程序遍历颜色,保存矩形中的当前颜色。
  3. 将矩形放入堆栈面板(以便更好地管理)。
  4. Stackpanel进入堆栈面板的列表,然后放在画布上。
  5. 画布显示在单独的窗口中。该画布必须可用,以保存为图像。(原来是无用的功能)

这部分代码消耗了大量的RAM,我对此有点烦扰。

例如,如果用户选择范围为0-255,则将出现3375个彩色框。(-(255x255x255)/(17x17x17)--)消耗70。

如果用户选择范围0-255,音调步骤5,那么将有132651色框.(-(255x255x255)/(5x5x5)--)消耗600

内存消耗最多的有三个标记。当我第一次创建这个应用程序时,我假设在每个循环变量“矩形”和"brushColor“被释放后,垃圾回收和重用,但我完全错了。他们有WeakReference。

最后,我尝试缓存这些变量,但是程序意外地开始工作。最后一个窗口没有颜色框,或者所有的框都是一种颜色。或此“指定的Visual已是另一个Visual或CompositionTarget的根”。我无法在不破坏程序的情况下解决这些错误,所以我保留了原样。

那么,在这种情况下,有什么更好的方法来减少内存消耗呢?我的实现对我来说已经足够好了,但我想知道如何使它变得更好。也许我漏掉了一些显而易见的东西,或者相反,我做了一些非常低效的事情,比如在矩形中存储颜色等等。

代码语言:javascript
复制
private void shuffle_colors1(List<StackPanel> stackPanels, Double colorBoxCount, int boxesInSingleRow, int stackPanelsCounter)
        {

            for (int redC = tempR; redC < crMax; redC++)
            {
                for (int greenC = tempG; greenC < cgMax; greenC++)
                {
                    for (int blueC = tempB; blueC < cbMax; blueC++)
                    {
                        var rectangle = new Rectangle(); // MARK 1
                        rectangle.Width = cBoxWidth;
                        rectangle.Height = cBoxHeight;
                        rectangle.Margin = border;

                        stackPanelColor = Color.FromRgb((byte)redC, (byte)greenC, (byte)blueC);
                         
                        brushColor = new SolidColorBrush(stackPanelColor); // MARK 2
                        displayedColors++;

                        rectangle.Fill = brushColor;
                        stackPanels[stackPanelsCounter].Children.Add(rectangle);
                        colorBoxCount++;
                           
                        if (colorBoxCount >= boxesInSingleRow)
                        {
                            AddNewStackPanel(stackPanels, stackPanelsCounter); // MARK 3
                            stackPanelsCounter++;
                            colorBoxCount = 0;
                        }
                              
                        blueC += bts - 1;
                    }
                   greenC += gts - 1;

                }
                redC += rts - 1;
            }
       }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-31 16:12:30

如果不实际进行一些调试,就很难判断实际问题,但我可能会提供一些提示:

使用内存分析器

从您的描述中可以看出,您已经这样做了,但是如果您确保清除包含对矩形或任何其他UI对象的引用的任何内容,则它们应该有资格进行收集。在您的示例代码中,我看不到确保重新创建或清除堆栈面板的任何内容。

不删除事件处理程序是泄漏的另一个常见原因。

但也可能会有臭虫。在应用程序发布了所有内容之后,我在windows辅助功能保持对UI元素的引用方面遇到了一些问题。Windows似乎会在一段时间后释放引用,但如果在集合之后没有释放内存,我仍然认为它是一个bug。这的症状是,当应该收集的UI对象只有一个可定位句柄或gcroot作为根引用时,而不涉及用户代码。但我找不到一个关于这个问题的参考。

重用对象

Wpf对象通常不会非常便宜地创建,因此您可能希望重用对象,而不是重新创建大量对象。只要你不改变方框的数量,我看不出为什么你不能简单地更新你的刷子的颜色特性

限制使用的wpf元素数

虽然在一个较小的网格中使用单独的UI元素可能是合理的,但是130 k元素听起来很不错。因此,一种选择就是将“音调步长”变量限制在一些相当大的值上。

但是,如果您想支持非常多的颜色,您可能会受益于仅仅使用一个WriteableBitmap来生成您想要的颜色布局。这样,您的内存使用量与所需像素的数量成正比,开销非常小。

有些功能,比如鼠标越位效果,会更复杂,但是大多数事情仍然可以通过在位图上使用常规的wpf元素来显示所选内容或任何你想要的东西。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74265707

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档