我正在构建业务应用程序,该应用程序将容纳50,000到150,000家公司。每个公司(数据库行)用4-5个属性/列(标题,位置,......)表示。 ORM是LINQ2SQL。
我必须做一些计算,为此,我对特定公司有很多疑问。现在,每次我需要的时候都会转到db,它会产生50-200个查询,具体取决于计算的复杂程度。我试图让所有公司都进行缓存,对于db中的10,000行(公司),它需要大约5.5MB的缓存。在这种情况下,我只有一个查询。
此应用程序将位于共享托管服务器上,因此我的资源有限。我很感兴趣,如果我尝试加载会发生什么,比方说100,000公司(行,对象)?或者把它放在缓存中?
是否有平均托管公司给ASP.NET应用程序的RAM限制?它是否依赖于专用的Applcation Pool(我可以将应用程序放到专用池中)?
选项:
- 将整个表加载到c#对象。我做了一些内存分析,10,000个对象需要5MB RAM
- 查询db以在需要时获取引用的对象。
任务:对于给定的公司A,建立连接公司的树。
表格和列:
公司:IdCompany,标题,地址,联系人
CompanyConnection: IdParentCompany,IdChildCompany
答案 0 :(得分:1)
您的共享主机可能是作为虚拟机运行的Windows Server上的IIS 7。这台机器的行为与任何普通机器一样 - 它不会“意识到”被共享或虚拟化。
当Windows超出物理RAM时,您应该期望Windows开始分页到磁盘,然后仅在页面文件填满磁盘时才会抛出内存不足错误。当然,您不希望将热缓存的任何部分分页到磁盘。
Windows本身可以开始唠叨内存不足,但这不是“紧急”,应用程序将继续能够请求RAM并继续给予它(尽管从页面文件中提供服务)。 / p>
如果您的应用程序可能崩溃并且保持损坏状态或部分事务,那么您应该采取防御措施并在启动操作之前检查内存是否可用。
使用伪装数据在循环中创建预期数量的对象,并在框中观察内存消耗 - 工作进程的工作集是要观察的工作集。您可以在任务管理器中执行此操作。
注意页面错误。这些是必须将内存操作定向到磁盘的事件。
此外,非常大的对象集可能导致长的垃圾收集周期> 1秒。这对于时间敏感的应用程序(如交易和市场数据)来说可能是个大问题。
希望有所帮助。
更新:我为大型数据挖掘应用程序执行类似的缓存。
每个ORM类型都有一个GetObject方法,它使用巨型缓存或转到磁盘然后更新缓存:Person.GetPerson(检查人员缓存,转到数据库,添加到人员缓存)
现在我的查询只返回结果的唯一键。然后使用上述方法获取每个密钥。在缓存建立之前,这一点很慢,但是......
关键是每个查询结果都指向内存中的同一个实例!这意味着由于共享,RAM占用空间要小得多。
然后缓存查询结果。当然。
如果对象不是不可变的,则每个对象写入都会在巨型缓存中更新自己的实例,但也会导致与该类型对象相关的所有查询缓存自身无效!
当然,在这个应用程序中,写入很少是它的主要参考数据。