3

Какой из ниже надреза кода более Сбор мусора эффективным с точки зрения временисбор мусора Java против локальной и глобальной переменной с Потокобезопасная

Class Test{...} 

Локальная переменная

private void function(){ 
    Test test = new Test(); 
    .... 
} 

Global Переменная

Test test = null; 
private void function(){ 
    if(test == null){ 
    test = new Test(); 
    } 
} 

Пусть Предположим, функция() вызова часто

EDIT

Вы все хорошо. Хорошо ответили. Теперь я пришел к точке,

CASE-1 является более эффективным, чем GC CASE-2, но с другой стороны CASE-1 не поточно. Таким образом, оба имеют за и против

.

+0

Меня больше беспокоят побочные эффекты наличия «глобальной переменной» (для меня это похоже на поле экземпляра). Такие, как потеря безопасности нитей. – Thilo

+1

В сценарии ** Global Variable ** используется lazy-load, что позволяет избежать постоянной переустановки 'test' каждый раз, когда вызывается' function() '. Это также сведёт к минимуму работу, выполняемую сборщиком мусора. С другой стороны, вы застряли бы с экземпляром «Test» в хранящейся памяти, которая была бы пустой тратой, поскольку экземпляр не использовался часто. –

+0

@TimBiegeleisen - вы можете уточнить? – TheLostMind

ответ

1

В случае 1 a Тест создан и становится доступным для GC при каждом вызове, и это создает много мусора. В случае 2 он создается один раз и, возможно, никогда не GCed.

Почему мы не всегда используем опцию 2 - она ​​может быть небезопасной. Давайте заменим Test на SimpleDateFormat, и функция() понадобится для синхронизации или не будет работать в многопоточном приложении. Синхронизация тоже стоит дорого. Таким образом, нам нужно решить, какой вариант лучше - новый объект каждый раз или синхронизация.

0

Ну, это зависит от использования функций и того, что определяется объектом в задаче. Я бы всегда говорил, создавайте объект только тогда, когда вам нужно. Нет причин, чтобы объект, сидящий вокруг, не использовался. Если вы планируете использовать этот объект за пределами своей функции, вы сначала захотите инициализировать его нулевой глобально, а затем при необходимости создадите объект.

Вы не должны беспокоиться о эффективности сбора мусора Java. Это эффективно. До тех пор, пока вы не станете 100-м на 100 и более объектов динамически постоянно, я бы не стал беспокоиться об этом.

+0

. Джеймс Комбс это простая иллюстрация в режиме реального времени() часто. Мы знаем, что GC очень эффективен, но я снова хотел бы знать, какая из них является хорошей практикой, чтобы избежать вызова GC? –

+0

Отметьте ответ, полученный от @Thilo –

1

Если у конструктора есть побочный эффект, ваши два варианта делают две разные вещи.


Если Test несет государство, Вариант 1 и Вариант 2 не может быть эквивалентна больше, либо (и вариант 2 не может быть поточно-сейф).

Дело в том, что многие люди ошибаются в использовании объектов даты или номеров формата Java, таких как Вариант 2. Это не работает хорошо, поскольку они не являются потокобезопасными.


Предполагая, что Test полностью без гражданства и вызов конструктора не имеет побочных эффектов (оба из которых вы, кажется, подразумевает), как насчет варианта 3:

private static final Test test = new Test(); 

private void function(){ 
    ..... 
} 

Нет GC активности вообще.


Или, если Test действительно несет государство или каким-то образом не поточно-, и вы хотите позвонить function в тугой петлей, Вариант 4:

private void function(Test test){ 
} 

void theCaller(){ 
    Test test = new Test(); 
    for (int i=0; i<10000; i++) { 
     function(test); 
    } 
} 

Поскольку метод является private вы чтобы перейти к менее удобному способу вызвать его во имя производительности.

Смежные вопросы