GC делает паузу, вызывая проблемы с производительностью - PullRequest
1 голос
/ 23 января 2012

Я только начал работать над проектом (я новичок, а не проект), который в качестве оптимизации производительности загружает 32 ГБ графических данных (узлов, ребер и т. Д.) В память и сохраняет их там.Это долгосрочная служба, поэтому данные должны оставаться в памяти в течение всего срока службы.Когда CLR запускает коллекцию Gen 2, возникают большие паузы (конечно), которые снижают производительность, в то время как GC сканирует Gen 2, отмечая все как достижимые объекты.

Что я хотел бы знать, так это доступные стратегии для управляемых приложений, которые должны хранить большие объемы данных в памяти?Каковы наилучшие способы запретить запуск коллекций Gen 2?

1 Ответ

1 голос
/ 24 января 2012

Есть несколько общих вещей, которые вы можете сделать в своей реализации, чтобы сделать ее более удобной для GC: относительно легким является уменьшение количества ссылок на объекты в вашем графе объектов.Например, замените:

class Graph {
    List<Node> roots;
    // ...
}

class Node {
    Node[] outwardEdges;
    // ...
}

Косвенными ссылками через идентификаторы узла:

class Graph {
   List<Node> roots;
   Node[] allNodes;
   // ...
}

class Node {
    int[] outwardEdges;
    // ...
}

или чем-то похожим, что соответствует вашему дизайну.Это уменьшает количество указателей в графе объектов, которые должен пройти сборщик.

Перенос данных в собственную кучу - это еще одна возможность, написать небольшую библиотеку JNI, которая предоставит вам интерфейс для выполнения операций, которые вы выполняете.необходимость.Это может окупиться другими способами: в прошлый раз, когда у меня была похожая проблема, мы решили существенно сэкономить пространство благодаря этому подходу, потому что у нас были в основном западные текстовые данные в наборе данных, которые занимали гораздо меньше места, закодированного как UTF8.Пока стоимость поиска в графе не тривиальна, издержки родного вызова вряд ли будут проблемой.

...