我刚刚开始研究一个项目(我不是新项目),因为性能优化将32GB的图形数据(节点,边缘等)加载到内存中并保存在那里。这是一个长期运行的服务,因此数据意味着在服务的生命周期内保留在内存中。当CLR触发Gen 2集合时,会有大的暂停(当然)会损害性能,而GC会扫描Gen 2将所有内容标记为可到达的对象。
我想知道的是,是否有可用于托管应用程序的策略,这些应用程序必须在内存中保留大量数据?防止第2代收藏品运行的最佳方法是什么?
答案 0 :(得分:1)
您可以在实现中执行一些常规操作以使其更加友好GC:相对简单的方法是减少对象图中对象引用的数量。例如,替换:
class Graph {
List<Node> roots;
// ...
}
class Node {
Node[] outwardEdges;
// ...
}
通过节点标识符进行间接引用:
class Graph {
List<Node> roots;
Node[] allNodes;
// ...
}
class Node {
int[] outwardEdges;
// ...
}
或类似的东西适合您的设计。这减少了收集器必须走的对象图中的指针数。
将数据转移到本机堆是另一种可能性,编写一个小型JNI库,为您提供执行所需操作的接口。这可以通过其他方式获得回报:上次我遇到类似的问题时,我们通过这种方法节省了大量空间,因为我们在数据集中主要使用西方文本数据,占用的空间远远少于编码为UTF8的空间。只要图表搜索的成本非常重要,那么本机调用的开销就不会成为问题。