Вопрос: Оптимизация jvm для строковых переменных в методах


В проекте, который я поддерживаю, я нашел класс 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. было бы улучшение производительности, если бы я сделал переменную публичным статическим финалом?
    (На самом деле существует так много таких функций, что я хочу знать, стоит ли их менять все)

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

Благодаря, Киран Мохан


4


источник


Ответы:


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

стоимость  (т.е. String объект) "fn" будем не  воссоздаваться, но будет поступать из постоянного пула строк.

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

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


6



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

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

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

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


3



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

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

String METHOD_NAME = "fn".intern();

Хотя я считаю его ненужным.

Сделать публичный статический финал хорош.


2



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

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


1



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

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


0



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

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

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

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

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

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

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


0



Я пойду на публичный статический финал, что увеличит предварительную подготовку.


-2