Загрузка одной единственной константы в jvm среди нескольких констант

В моем коде я должен использовать некоторые постоянные значения, поэтому я создал служебный класс

public class ConstantUtility {
    public final static String category1_name1="category1/name1";
    public final static String category1_name2="category1/name2";
    public final static String category1_name3="category1/name3";
    .
    .
    .
    public final static String category2_name100="category2/name100";
    public final static String category2_name101="category2/name101";
    .
    .
    .
}

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

Константы 2000 года разделены на 6 категорий. Я пытался использовать 6 статических классов, но все равно. Когда jvm находит статический класс, он загружает каждую статическую переменную в память.

По сравнению с памятью строковых констант, которую я действительно использую, память всех тех констант, которую я не использую для загрузки в jvm, намного больше.

Вопрос: Как я могу загрузить в память только одну константу из всех этих констант.


person Sudheer    schedule 28.06.2016    source источник
comment
Если это то, как они действительно выглядят, то ни в одном из них нет необходимости. Просто вычисляйте их по мере необходимости   -  person user207421    schedule 28.06.2016
comment
@EJP, я не понимаю, что ты пытаешься сказать. Вы предлагаете использовать статические переменные.   -  person Sudheer    schedule 28.06.2016
comment
Вам не нужно хранить 2000 строк вида "/category"+i+"/name"+j. Вы можете вычислить те, которые вам нужны, во время выполнения.   -  person user207421    schedule 28.06.2016
comment
Я не уверен, стоит ли вам беспокоиться о производительности, если у вас действительно нет проблем с производительностью. В системе производственного уровня 2000 констант не так уж и плохо. Кроме того, общедоступные статические окончательные строки являются константами времени компиляции, они значительно ускорят ваше приложение.   -  person TheLostMind    schedule 28.06.2016
comment
Если этот пример нереален, непонятно, о чем вы спрашиваете, но если есть какое-то правило их построения, вы можете просто применить это правило.   -  person user207421    schedule 28.06.2016
comment
Категория @EJP - это что-то вроде приложения, аудио... не категории 1, 2... то же самое касается и имен. Я привел это просто для примера.   -  person Sudheer    schedule 28.06.2016
comment
@TheLostMind, вы правы, это больше похоже на проблему с памятью, но код будет использоваться для веб-приложения, поэтому проблем не будет. Но я считаю это очень плохим дизайном.   -  person Sudheer    schedule 28.06.2016
comment
@Sudheer - Ну, строки 2K - это действительно не очень хороший дизайн. Вы можете генерировать их динамически, как говорит EJP.   -  person TheLostMind    schedule 28.06.2016
comment
@EJP, @TheLostMind - как насчет перечислений. если я использую перечисления, это может принести пользу.   -  person Sudheer    schedule 28.06.2016
comment
Вам нужно привести какие-то конкретные примеры, но для начала я бы нормализовал это. Например, у вас есть только шесть категорий, поэтому вам не нужно взрывать все возможные комбинации категорий и имен. Я бы серьезно подумал о том, чтобы вообще не иметь каких-либо из этих констант и позволить пулу строк творить свое волшебство.   -  person user207421    schedule 28.06.2016


Ответы (4)


И просто для уверенности: вы спрашиваете об этом, потому что делаете какой-то «встроенный» проект; и вы столкнулись с проблемами памяти; и вы провели профилирование/анализ и обнаружили, что наличие этих 2000 строк действительно является проблемой в вашем приложении? Потому что: если вы ничего из этого не сделали — с чего вы взяли, что у вас действительно есть проблема, которая требует, чтобы вы потратили на нее время?

И примечание: сам факт того, что у вас есть 2000 констант; многие из них "неиспользуемые"... очень многое указывает на то, что вам следует меньше беспокоиться о влиянии такого дизайна на потребление памяти; а на самой конструкции.

Честно говоря, это плохо пахнет с точки зрения «вероятно, не очень хорошего дизайна» в первую очередь.

person GhostCat    schedule 28.06.2016
comment
Я согласен с Jagermeister, @Sudheer, вы ожидаете, что машина будет делать .5, которая понимает только 0 или 1 - person Gaurava Agarwal; 28.06.2016
comment
@Sudheer, я имею в виду, что JVM либо ничего не загрузит, что означает 0, либо все константы, что означает 1. Она не может выполнять половину работы. Использование констант имеет свои плюсы и минусы. Одним из недостатков, который не всегда учитывается, является проблема, с которой вы сталкиваетесь. Вам необходимо изменить структуру определения констант. Так что одна группа констант определена в одном классе. Если использование памяти является основной проблемой, группируйте константы на основе функциональности, а не на уровне приложения. - person Gaurava Agarwal; 28.06.2016

Вы можете создавать файлы свойств. Это простые текстовые файлы, в которых вы можете хранить пары ключ-значение и анализировать их с помощью стандартных классов Java: Свойства

Затем вы можете загрузить только те файлы, которые вам нужны. Вы сказали, что разделили свои ценности на 6 категорий. Вы можете создать 6 файлов и загружать только один файл, который вам нужен, когда он вам нужен.

person sotix    schedule 28.06.2016

Это практика, которую часто можно увидеть.

  • В команде это вызывает ненужные циклы контроля версий/слияния.
  • Компилятор в используемом источнике импортирует константу в самом классе, а в .class больше не будет находиться импорт класса констант. Таким образом, если константа получает другое значение, устаревшее значение остается в используемом классе (требуется ручная очистка + сборка).
  • Новый код разбит на два места, что не "течет" максимально быстро, также для поиска и чтения.

Как вы упомянули, можно облегчить проблему, имея несколько констант, определяющих классы/интерфейсы/перечисления.

Альтернативы (в некоторой степени) существуют. JAXB позволяет маршалировать между объектами XML и Java.

@XmlAttribute("surname")
public String surname; // <... surname="...">

Аннотацию выше можно удалить, так как поле имеет точное имя. Кстати: не вводите константы для значений аннотаций, так как аннотации могут обрабатываться.

Это показывает два способа введения констант, и я добавляю перечисление:

  • по аннотации - обрабатывается в java
  • по отражению (хотя и неэффективно)
  • по перечислению: enum Category1 { name1, name2 }

По общему признанию, это должно соответствовать варианту использования.

Бизнес-логика кажется самой большой проблемой: множество небольших доменов и специфичный для конкретного случая код для обработки бизнес-правил. Значения домена могут быть сгенерированы как перечисление из базы данных (или наоборот).

person Joop Eggen    schedule 28.06.2016
comment
Как создать перечисление из базы данных? Экземпляры перечисления предопределены во время компиляции, не так ли? - person Basil Bourque; 28.06.2016
comment
@BasilBourque Извините, я имел в виду, что можно генерировать таблицы БД с перечислениями SQL или строками значений java-источников, которые затем необходимо скомпилировать. - person Joop Eggen; 28.06.2016
comment
Я предлагаю вам расширить это в вашем ответе. Я думаю, вы говорите о программной генерации текста для исходного кода Java, который затем скомпилируется в приложении, но я не уверен. - person Basil Bourque; 28.06.2016
comment
Да, небольшое приложение, которое запрашивает базу данных и генерирует перечисление java или что-то в этом роде. Это очень сильно зависит от того, какие константы, поэтому я воздержусь от написания чего-либо. Начинайте писать такой инструмент, когда создали такой класс вручную, и в будущем ожидается больше значений. Поместите все эти сгенерированные исходники в отдельный проект библиотеки для управления версиями. - person Joop Eggen; 28.06.2016

По сути, при загрузке класса JVM загружает все статические переменные и сохраняет их в памяти. Если вы хотите загружать только константы по требованию. Вы должны написать определенную логику, используя системные команды и вызывать из кода Java. Или переместите все константы в файл и извлекайте необходимые константы по мере необходимости. Но с точки зрения производительности это не так уж и хорошо.

person JP Bose    schedule 28.06.2016
comment
Да, переместите свою константу в файл и выполните команду «grep» с вашим именем константы и загрузите результат в переменную java. - person JP Bose; 28.06.2016
comment
@JPBose - Нет, это неправильный подход. Это на самом деле ужасный способ как с точки зрения дизайна, так и с точки зрения производительности. - person TheLostMind; 28.06.2016
comment
@TheLostMind верен, я не хочу использовать static для этой проблемы, потому что это был бы плохой дизайн, а вызов нативного кода из java-кода снижает производительность. - person Sudheer; 28.06.2016