2

我有一个使用 .Net 4.0 的游戏服务器项目。我正在使用 MemoryCache 类并缓存许多可以​​由多个用户同时修改的对象,以实现快速 i/o 和同步。最近游戏发布后,我发现我的设计有问题。因为这些缓存对象是长生命周期的对象,它们都进入 GC gen 2,并且很难被释放,所以 gen 2 堆变得非常大(5 天后大约 8 GB)并且对于完整的 GC 来说花费的时间太长。

经过几天的谷歌搜索,我认为这也许是不使用长寿命对象来避免大 gen 2 堆的最佳方法。但我不知道该怎么办。这些对象是从db加载,根据用户请求修改,然后保存回db,序列化到byte[]太复杂,无法保存到memcached,甚至可以序列化,(从memcached读取->修改->写入back) 也不是线程安全的操作。

有什么建议么?

4

3 回答 3

0

该服务器必须在内存中本地缓存所有内容是否有原因?如果您从服务器连接到数据库,我可以理解您为什么会遇到此类问题以及为什么将它们缓存在内存中。然而,有很多缓存框架可以跨多个应用程序实例工作,例如 Memcached。

当然,它不会像在内存中那样快,但是在检索对象方面实际上是否存在性能问题,或者您是否只是先发制人地出现了速度问题并进行了预优化?就好像你有然后你可能会发现,如果你水平扩展你的应用程序并停止在内存中缓存并将责任推到另一个系统,你可能会让每个服务器实例稍微慢一些,但扩展起来会更容易和更快。

于 2012-10-15T12:56:37.120 回答
0

我能想到几个建议

  • 首先,您是否尝试过使用服务器 GC这将堆分成多个堆(每个处理器一个),这些堆被并行收集,以提高多处理器机器上的吞吐量。这可能有助于彻底解决您的问题。
  • 如果这没有帮助并且您的第 2 代堆仍然需要很长时间才能收集,那么您应该考虑使用某种外部缓存框架(如 Memcached)。在不知道更多细节的情况下,这可能是我的首选方法。
  • 或者,您可以考虑使用对象池并重新利用现有对象,而不是分配和释放新对象。

我能想到的唯一其他解决方案是在即将发生完整 GC 时重定向到另一个服务器服务器(关于何时将发生完整 GC 的通知是 .Net 3.5 SP1 功能)但是这可能更多比上面的第二个选项复杂。

于 2012-10-15T13:27:36.700 回答
0

为什么不为缓存对象配置生命周期?可能没有必要存储这么多 N 小时/天未使用的对象。

当它没有帮助时,您需要更改缓存机制。此外,当您需要存储如此大量的对象和如此长的时间时,您需要不止一台服务器。您可以使用本地托管或云,两者都有称为分布式缓存的缓存机制。在 .NET 的前提下,它可以是 AppFabric 缓存,在云中使用 Windows Azure - 也非常类似于 AppFabric。

因此,当生命周期无济于事时,我对您的建议是在云(Windows Azure、Amazon AWS)或本地(AppFabric)中使用分布式缓存

于 2012-10-17T14:11:53.670 回答