c# – 托管环境中的临时内存
我正在C#中进行流体模拟.每个循环都需要计算出离散点处的流体速度.作为该计算的一部分,我需要几十千字节的临时空间来保存一些双[]数组(数组的确切大小取决于某些输入数据).数组只需要使用它们的方法的持续时间,并且有一些不同的方法需要这样的划痕空间.
正如我所看到的,构建暂存数组有几种不同的解决方案: >每次调用该方法时,使用’new’从堆中获取内存.这是我在开始做的,但是它对垃圾收集器施加了很大的压力,每秒钟的一秒钟或两秒钟的ms峰值真的很烦人. … 有没有人有类似问题的经验?从经验中提供的任何建议/经验教训? 解决方法
我同情你的情况当我在Roslyn工作时,我们非常仔细地考虑了从分配临时工作阵列的收集压力导致的潜在性能问题.我们解决的解决方案是一个汇集策略.
在编译器中,数组大小往往很小,因此频繁重复.在你的情况下,如果你有大阵列,那么我会做的是跟随汤姆的建议:简化管理问题,浪费一些空间.当您向池中请求一个大小为x的数组时,将x乘以最接近的幂数,并分配一个该大小的数组,或者从池中获取一个数组.调用者得到一个有点太大的数组,但是它们可以被写入来处理它.在池中搜索适当大小的数组不应太难.或者你可以维护一堆池,一个池的大小为1024,一个为2048,等等. 编写一个线程安全池不是太难,或者你可以使池线程静态,每个线程有一个池. 令人难以置信的是在游戏池中恢复记忆.有几种方法来处理这个问题.首先,如果他们不想牺牲收集压力,您可以简单地要求池内存的用户调用“返回池”方法. 另一种方法是在数组周围编写一个外观封装,使其实现IDisposable,以便您可以使用“using”(*),并在该对象上重新将其重新置于池中. (确保让终结者回到“我需要定稿”位.)复活的终结者让我紧张;我个人喜欢以前的做法,这是我们在罗斯林做的. (*)是的,这违反了“使用”应该表明非托管资源正在返回到操作系统的原则.本质上,我们通过自己的管理来将托管内存视为非托管资源,所以不是那么糟糕. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |