Как уменьшить общий объем памяти, сжимая мои объекты в Java? - PullRequest
1 голос
/ 02 декабря 2009

У меня есть таблица с примерно 20 столбцами, в основном состоящими из десятичных чисел. Эта таблица имеет почти 1,5 млн строк. Но в них мало общего: например, column1 состоит только из 100 различных строк, column2 содержит почти 1000, а column3 содержит почти 500.

Сейчас я храню все эти значения столбцов на карте с ключом в качестве первых 5 столбцов и данными в качестве остальных столбцов. Моя задача такова, мне нужно инициализировать все это в начале задачи.

Какой шаблон (например, Flyweight и т. Д.) Или структуру данных мне следует использовать, чтобы минимизировать объем моего хранилища объектов?

Зачем мне нужна предварительная загрузка всех данных?

Предположим, что все данные таблицы представлены в виде дерева, и жертвы могут находиться на любом листе, стволе или в корне. Поэтому для каждой записи [это исходит из другого места] мне нужно посмотреть, есть ли совпадения в дереве.

Ответы [ 3 ]

2 голосов
/ 02 декабря 2009

Интернализация не лучший вариант. Сбор мусора из PermSpace возможен, но ничего, для чего виртуальная машина не оптимизирована.

Вы можете реализовать свою собственную реализацию CharSequence , которая поддерживается общими массивами char [].

С реализацией CharSequence вы сможете реализовать базовую семантику совместного использования, такую ​​как интернализованные строки или более сложные, с учетом подстрок и других проекций.

Пользовательская реализация CharSequence также может быть оптимизирована для выполнения меньшего количества выделенных памяти , чем класс String, который копирует char [] вокруг (по соображениям безопасности, которые не нужны, если у вас есть вспомогательный char [] ваш полный контроль). Даже new String("..").intern() создаст новый экземпляр String (массив char []), который быстро собирается мусором.

1 голос
/ 02 декабря 2009

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

Не могли бы вы рассказать, что ваша задача пытается достичь с помощью всех этих данных, кэшированных на карте?

Является ли идентификация "жертвы" частью ключа или частью объекта? Если часть объекта, как вы выбираете ключи, которые выбирают объекты, которые вам нужны? Другими словами; Похоже, вы пытаетесь воспроизвести функциональность, в которой база данных очень хороша.

Если ваша проблема заключается в том, что содержимое вашей таблицы не отображается легко в древовидной структуре, вы можете добавить эту информацию таким образом, чтобы ее можно было использовать через интерфейс БД.

0 голосов
/ 02 декабря 2009

Если ваш процесс загрузки данных может поддерживать его, то не так уж сложно реализовать что-то вроде String.intern () без побочных эффектов permgen GC.

Для любого хэшируемого элемента данных вы можете просто иметь Map<T,T> для поиска ранее существовавших экземпляров. Так что для строки:

Map<String,String> stringCache = new HashMap<String,String>();
...
String sharedValue = stringCache.get(loadedValue);

Процесс, который загружает данные откуда угодно, будет по-прежнему создавать временные строки, но они будут быстро обработаны GC. Не зная подробностей о том, откуда поступают данные, сложно комментировать, нужны ли эти временные объекты ... хотя мне сложно найти способ обойти это. В любом случае они будут быстро восстановлены в процессе загрузки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...