JVM оптимизация для строковых переменных в методах - PullRequest
4 голосов
/ 07 апреля 2011

В проекте, который я поддерживаю, я нашел класс java с методом "fn", подобным показанному ниже

class Test{

public void fn(){
    String METHOD_NAME = "fn";
    ...
    sysout("In " + METHOD_NAME);
}
}

Программа работает бесконечно, и метод 'fn' вызывается непрерывно и с очень высокой частотой. Вопрос

  1. будет ли переменная METHOD_NAME создаваться каждый раз, когда вызывается функция fn ()?
  2. будет ли JVM выполнять некоторую оптимизацию, чтобы переменная METHOD_NAME не собиралась мусором и не использовалась повторно при следующем вызове fn ()?
  3. Было бы улучшение производительности, если бы я сделал переменную общедоступной статической окончательной?
    (На самом деле таких функций так много, что я хочу знать, стоит ли их менять все)

(я думаю, что пул струн здесь играет какую-то роль)

Спасибо, Киран Мохан

Ответы [ 7 ]

6 голосов
/ 07 апреля 2011

Да, переменная METHOD_NAME будет создаваться каждый раз при вводе метода, но это очень и очень дешевая операция (на самом деле создание 2 переменных обходится дороже, чем создание 1).

Значение (т. Е. Объект String) "fn" будет не воссоздано, но будет происходить из пула константных строк.

Однако , выражение "In " + METHOD_NAME будет пересчитано и каждый раз будет создаваться новый объект String, поскольку он не является выражением постоянной времени компиляции .

* 1021.* Если METHOD_NAME, где static final, то это выражение также будет константой времени компиляции и, следовательно, будет происходить из пула констант.
3 голосов
/ 07 апреля 2011

Переменные не собираются мусором - объекты есть.

"fn" - строковый литерал, поэтому он будет интернирован . Он не будет собирать мусор (по крайней мере, пока этот ClassLoader активен; не уверен, есть ли один пул для каждого CL или один для всей JVM, но это, вероятно, не имеет значения), и один и тот же строковый объект будет использоваться при каждом вызове.

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

Если вы сделаете его окончательным в методе (т.е. все еще в качестве локальной переменной), то может иметь тот же эффект - я не уверен.

2 голосов
/ 07 апреля 2011

"FN" будет интернирован. Следовательно, один и тот же объект будет использоваться снова и снова.

В худшем случае вы можете заменить его на:

String METHOD_NAME = "fn".intern();

Хотя я думаю, что это ненужно.

Публикация статического финала - это хорошо.

1 голос
/ 07 апреля 2011

Насколько мне известно, METHOD_NAME - ссылка на строку 'fn' будет размещаться при каждом вызове функции fn ().Однако объект String 'fn' должен быть выделен один раз, поскольку он является константой String и будет помещен в пул String.

Замена его на открытый статический финал может быть хорошей идеей, но длястиль программирования, а не производительность.

0 голосов
/ 07 апреля 2011

будет ли переменная METHOD_NAME создаваться каждый раз, когда вызывается функция fn ()?

Переменная будет «создана» (лучше «установлена»), но строка - нет (поскольку это внутренняя строка, находящаяся в пуле строк JVM). Так что это просто новая ссылка на ту же строку.

будет ли JVM выполнять некоторую оптимизацию, чтобы переменная METHOD_NAME не собиралась мусором и не использовалась повторно при следующем вызове fn ()

Переменная METHOD_NAME - это просто имя для ссылки. Указанная строка может находиться в пуле строк.

Было бы улучшение производительности, если бы я сделал переменную общедоступной статической окончательной?

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

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

0 голосов
/ 07 апреля 2011

Строковые литералы помещаются в постоянный пул.Нет никакого смысла помещать строку в статический финал - это поведение гарантируется JLS.

(и да, строка также будет интернирована, хотя это не особенно важно для ваших задач)

0 голосов
/ 07 апреля 2011

Вы идете на публичный статический финал, который увеличит преформанс.

...