日安。
我创建了一个小程序来创建调色板。没事的,它正常工作。程序截图
所创建的纹理作为一种材料用于三维建模。程序的工作方式如下:
这部分代码消耗了大量的RAM,我对此有点烦扰。
例如,如果用户选择范围为0-255,则将出现3375个彩色框。(-(255x255x255)/(17x17x17)--)消耗70。
如果用户选择范围0-255,音调步骤5,那么将有132651色框.(-(255x255x255)/(5x5x5)--)消耗600!
内存消耗最多的有三个标记。当我第一次创建这个应用程序时,我假设在每个循环变量“矩形”和"brushColor“被释放后,垃圾回收和重用,但我完全错了。他们有WeakReference。
最后,我尝试缓存这些变量,但是程序意外地开始工作。最后一个窗口没有颜色框,或者所有的框都是一种颜色。或此“指定的Visual已是另一个Visual或CompositionTarget的根”。我无法在不破坏程序的情况下解决这些错误,所以我保留了原样。
那么,在这种情况下,有什么更好的方法来减少内存消耗呢?我的实现对我来说已经足够好了,但我想知道如何使它变得更好。也许我漏掉了一些显而易见的东西,或者相反,我做了一些非常低效的事情,比如在矩形中存储颜色等等。
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;
}
}发布于 2022-10-31 16:12:30
如果不实际进行一些调试,就很难判断实际问题,但我可能会提供一些提示:
使用内存分析器
从您的描述中可以看出,您已经这样做了,但是如果您确保清除包含对矩形或任何其他UI对象的引用的任何内容,则它们应该有资格进行收集。在您的示例代码中,我看不到确保重新创建或清除堆栈面板的任何内容。
不删除事件处理程序是泄漏的另一个常见原因。
但也可能会有臭虫。在应用程序发布了所有内容之后,我在windows辅助功能保持对UI元素的引用方面遇到了一些问题。Windows似乎会在一段时间后释放引用,但如果在集合之后没有释放内存,我仍然认为它是一个bug。这的症状是,当应该收集的UI对象只有一个可定位句柄或gcroot作为根引用时,而不涉及用户代码。但我找不到一个关于这个问题的参考。
重用对象
Wpf对象通常不会非常便宜地创建,因此您可能希望重用对象,而不是重新创建大量对象。只要你不改变方框的数量,我看不出为什么你不能简单地更新你的刷子的颜色特性。
限制使用的wpf元素数
虽然在一个较小的网格中使用单独的UI元素可能是合理的,但是130 k元素听起来很不错。因此,一种选择就是将“音调步长”变量限制在一些相当大的值上。
但是,如果您想支持非常多的颜色,您可能会受益于仅仅使用一个WriteableBitmap来生成您想要的颜色布局。这样,您的内存使用量与所需像素的数量成正比,开销非常小。
有些功能,比如鼠标越位效果,会更复杂,但是大多数事情仍然可以通过在位图上使用常规的wpf元素来显示所选内容或任何你想要的东西。
https://stackoverflow.com/questions/74265707
复制相似问题