Ленивые и отложенные вопросы TreeViewer
-
22-09-2019 - |
Вопрос
На самом деле у меня есть два вопроса, но они в некотором роде связаны, так что здесь они объединены в один...
Как обеспечить сборку мусора из узлов дерева, которые в данный момент не отображаются, используя TreeViewer
(SWT.VIRTUAL
) и ILazeTreeContentProvider
?Если узел имеет 5000 дочерних элементов, как только они отображаются средством просмотра, они никогда не отпускаются,
следовательно, ошибка нехватки памяти, если ваше дерево имеет большое количество узлов и листьев и недостаточно большой размер кучи.Есть ли какая-то лучшая практика, как избежать утечек памяти, вызванных тем, что never closed view содержит treeviewer с большими объемами данных (сотни тысяч объектов или даже миллионы)?Возможно, существует какой-то интерфейс обратного вызова, который обеспечивает большую гибкость с элементами viewer / content provider?
Можно ли комбинировать выделенные (DeferredTreeContentManager
) И ленивый (ILazyTreeContentProvider
) загрузка для одного TreeViewer
(SWT.VIRTUAL
)?Насколько я понимаю, просмотрев примеры и API, возможно использовать только любой из них в данный момент времени, но не оба в сочетании, например,
извлекайте ТОЛЬКО видимые дочерние элементы для данного узла И извлекайте их в отдельном потоке, используя Job API.Что меня беспокоит, так это отложенный подход
загружает ВСЕХ дочерних элементов.Хотя в другом потоке вы все равно загружаете все элементы
даже если одновременно отображается только минимальное подмножество.
При необходимости я могу предоставить примеры кода для своих вопросов...
В настоящее время я сам борюсь с ними, поэтому, если мне удастся что-то придумать за это время, я с удовольствием поделюсь этим здесь.
Спасибо!
С уважением, Свилен
Решение
Я иногда нахожу фреймворк Eclipse шизофреническим.Я подозреваю , что DeferredTreeContentManager
поскольку это относится к ILazyTreeContentProvider
это один из таких случаев.
В другом примере на EclipseCon в прошлом году они рекомендовали вам использовать фабрики адаптеров (IAdapterFactory) для адаптации ваших моделей к контексту привязки, необходимому в данный момент.Например, если вы хотите, чтобы ваша модель отображалась в виде дерева, сделайте это таким образом.
treeViewer = new TreeViewer(parent, SWT.BORDER);
IAdapterFactory adapterFactory = new AdapterFactory();
Platform.getAdapterManager().registerAdapters(adapterFactory, SomePojo.class);
treeViewer.setLabelProvider(new WorkbenchLabelProvider());
treeViewer.setContentProvider(new BaseWorkbenchContentProvider());
Зарегистрируйте свой адаптер, и BaseWorkbenchContentProvider найдет адаптацию на заводе.Замечательно.Звучит как план.
"О, кстати, когда у вас есть большие наборы данных, пожалуйста, делайте это таким образом", - говорят они:
TableViewertableViewer = new TableViewer(parent, SWT.VIRTUAL);
// skipping the noise
tableViewer.setItemCount(100000);
tableViewer.setContentProvider(new LazyContentProvider());
tableViewer.setLabelProvider(new TableLabelProvider());
tableViewer.setUseHashlookup(true);
tableViewer.setInput(null);
Оказывается, что первый и второй примеры не только несовместимы, но и взаимоисключающи.Эти два подхода, вероятно, были реализованы разными командами, у которых не было общего плана, или, возможно, API находится в середине перехода на общую платформу.Тем не менее, вы предоставлены сами себе.