2010-01-14 33 views
2

基本上我正在处理一个处理很多大型视频和图像文件的程序,而我正在努力处理它的内存管理方面,因为我从来没有处理过像这样的任何事情。对于内存密集型.net程序,是否有很好的软件开发“模式”?

例如,它将所有这些图像存储在数据库中,并加载视频列表,然后您可以在视频之间切换并查看视频中的图像。现在,它始终将所有这些图像都保存在内存中,这就消耗了很多空间。我知道我可以懒加载图像,但一旦你来回切换,你会把它们全部卡在内存中。

我想尽可能利用WPF数据绑定功能和MVVM,但是如果我需要查看不同的架构,我会。

我只是在寻找一般建议,提示,文章链接,或任何可能的帮助。

+0

你需要某种智能高速缓存方案,它似乎...... – 2010-01-14 22:26:02

+4

C++可能是一个更好的模式。 =) – 2010-01-14 22:34:32

+2

从某种意义上说,如果您的房子有可能着火,最好在水下建造它。 – 2010-01-14 23:35:34

回答

1

似乎要提高原始性能,你实际上想要避免模式。他们有他们的用途,不要误解我的意思,但是如果您想要以最高性能爆炸视频,那么您最后需要做的事情是引入抽象层,这些抽象层旨在编写更高质量的代码,而不是提高应用程序性能。

+0

模式不一定是抽象或额外的缓慢层。他们中的许多人只是简单地尝试和测试了常见问题的工程方法。 – Crashworks 2010-01-14 23:37:13

+0

@Crash:同意。我正在考虑GOF设计模式。那本书之外有一个世界。 ;-) – 2010-01-14 23:43:08

1

this article on informIt关于这个问题有很多很好的信息,虽然它更多的是c和C++。

静态分配模式:分配存储器前面

它表明, 池分配模式:分配存储器中相同大小的块

智能:需要的对象

固定大小的缓冲图案的预先分配池指针模式:使指针可靠

垃圾回收模式:自动回收丢失的内存

垃圾压实机模式:自动碎片整理和回收内存

3

的事情之一,你可以看看是数据虚拟化,这是不是在WPF默认提供的(他们提供的UI虚拟化,而不是)。数据虚拟化可以说'在可见的情况下加载和绑定项目/项目范围的数据,然后在不可见时卸载“。

下面是描述一个具体的实现,你可能能够原样使用或改编了一大篇:

http://www.codeproject.com/KB/WPF/WpfDataVirtualization.aspx

3

这听起来像你遇到的主要问题是没有这么多的应用程序的性能密集程度(像固定大小的缓冲区和静态分配之类的东西会有所帮助),但是它的整个内存占用量。控制虚拟化的方法就是控制虚拟化。

延迟加载可以让你在一半的地方:在某些事情需要它之前,你不会真正创建对象。这很好,但用户使用应用程序的时间越长,在UI中访问的对象越多,创建的对象越多,最终应用程序内存不足。

所以你想抛弃用户不再需要的对象。找出用户不需要的对象可能是一个难题,但它也可以像假设用户不需要最近使用的对象那样简单。您使用最近最少使用(LRU)缓存来执行此操作。

这与MVVM模式完全一致。在您的视图类,你让你的属性获取该对象使用这个伪代码:

if object hasn't been loaded 
    load object 
add object to the LRU cache (whether you loaded it or not) 
return object 

The LRU cache I wrote保持它包含的对象的一个​​简单的队列。当你将一个对象添加到缓存中时,如果它不在队列中,它将被添加到缓存中,如果它已经在队列中,它将被移到后面。

如果在添加对象时队列处于其容量状态,则它将弹出队列前面的任何内容(这是最近使用的最少的那个),并引发事件DiscardingOldestItem

该事件是对象有机会告诉任何可以引用它的任何事物(即它是属性的视图对象),它需要被丢弃(可能通过引发它自己的事件)。视图对象的事件处理程序应该首先引发PropertyChanged事件。如果在执行此操作时调用属性getter,那么仍然有一个绑定在某处仍在查看该属性,因此它不应该被丢弃。 (另外,由于getter被调用,对象刚刚移动到队列的后面。)否则,它可以被丢弃。

(请注意,如果你在UI中可见比高速缓存可以容纳更多的物品,这个小舞将成为无限循环,你会得到一个堆栈溢出。)

一个更复杂的方法将有当应用程序开始在内存不足时LRU缓存开始丢弃旧项目(它现在使用固定容量)。这是一个直截了当的改变,但是如果你做出这样的改变,上一段中描述的情景就是你需要给予更多思考的东西;一个非常大的对象可能会导致整个用户界面进入kablooey。

0

“我知道我能延迟加载图像, 但一旦你切换回和 来回你得到所有的人都陷在 记忆。”

这不符合我的理解。通过删除所有引用,图像可以像其他任何东西一样得到垃圾收集。你确定你没有参考他们的地方吗?试试像memprofilerANTS这样的内存分析器,看看发生了什么。

那些谁发现了这个问题,寻找一般模式(不WPF),以减少内存,著名的一个(这是我从来没有见过使用!)是The Flyweight pattern

+0

当然,他们可以被垃圾收集,但然后我不得不摆脱我的引用...我不想摆脱引用,他们正在使用。我想摆脱这些对象引用的集合。 – 2010-01-15 16:05:43

+0

图像引用的是什么样的集合? (“那些对象”==图像?) – Schneider 2010-01-15 21:43:16

相关问题