【问题标题】:Entity Framework, binary data and LOH实体框架、二进制数据和 LOH
【发布时间】:2012-08-28 18:23:54
【问题描述】:

我需要在数据库(MS SQL)中存储大量二进制数据,并通过 EF 与该数据库进行交互。不幸的是,EF 不支持 FILESTREAM(更准确地说,没有流支持)。

所以,我决定以块的形式存储数据。 Chunk 只是一个实体类型:

public class Data
{
  public int Id { get; set; }
  public Collection<Chunk> Chunks { get; set; }
}

public class Chunk
{
  public int Id { get; set; }
  public int DataId { get; set; }
  public byte[] Content { get; set; }
}

首先,我想将块大小限制为某个最佳值,比如 1 Mb。
但后来我想起了大物体和 LOH。

据我了解,每个Chunk.Content 实例都将被视为具有以下后果(尤其是内存碎片)的大对象。因此,密集创建Chunk 对象最终将导致OutOfMemoryException(它是一个“24/7”应用程序,使用该二进制数据是应用程序的主要目的)。

我不能为数据块重用任何缓冲区,因为我使用的是 EF...
我应该减小块大小,使其更低,然后是 85K?
或者是偏执狂? :)

【问题讨论】:

  • 你必须将流存储到数据库吗?我遇到了很多问题,比如性能、压缩等。
  • @DarthVader:由于 EF 限制,我无法将数据存储在 FILESTREAM 中,如果你问过我的话。
  • 不,我是说将文件存储在 NAS 或本地,然后将位置存储到数据库。
  • @DarthVader:这也是我正在考虑的替代方案......但是,不幸的是,这种方法的主要缺点是可能会错误地定位两个存储,尤其是当您需要备份/恢复数据库时。这对我来说意义重大。

标签: c# .net entity-framework large-object-heap


【解决方案1】:

只有当您同时在内存中有太多块时才会出现 LOH 碎片问题,但从您的描述看来,每个“进程”都会有一个块。您期望有多少个并发进程?如果您希望拥有许多进程,您很可能还希望硬件具有足够的处理能力和内存(64 位平台)。处理这么多并行块不是硬件的真正限制吗?

无论如何,如果您需要将流存储到数据库,您应该简单地使用 FILESTREAM 而不使用 EF。不惜一切代价继续使用 EF 是架构失败。

【讨论】:

  • Ladislav,处理数据将是 WCF 服务的一部分,所以我需要处理并发块处理。我对NextObjPtr 感到困惑。据我了解,从堆分配内存会导致NextObjPtr 增加,而堆的压缩减少NextObjPtr。因为 LOH 永远不会被压缩,所以 LOH 的NextObjPtr 永远不会减少,大对象的连续分配会导致透视上的 OME。我错了吗?
  • 在这里找到:blogs.msdn.com/b/maoni/archive/2006/04/18/…:“活动大对象之间的空闲块被串入一个空闲列表,用于满足大对象分配请求”。因此,堆空间将被有效地重用。
  • 内存消耗不会无限增长。如果块被释放,它可以被重用。 OME 是由碎片引起的,其中没有更多的内存要分配,并且 LOH 中没有具有请求大小的空闲块(但 LOH 中的总空闲内存大于请求的大小)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-20
  • 1970-01-01
  • 2013-07-21
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
相关资源
最近更新 更多