2

Чтобы прояснить этот вопрос, рассмотрите сценарий, в котором я создаю активность Android, которая просто считывает данные из внешнего источника и использует эти данные в TextView. Я вижу резкие различия в производительности со следующими двумя сценариями:Android - Выполнение локальных переменных активности и переменных экземпляра

  1. Чтение внешних данных и заполнение переменных экземпляра Activity для использования во всей Деятельности. Результаты во время выполнения 2220.479170 мс, а DalvikVM освобождает память 12 раз.
  2. Чтение внешних данных в локальные переменные каждый раз, когда их необходимо использовать в методах класса. Результаты в 1150.434916 мс, а DalvikVM освобождает память 6 раз.

Как вы можете видеть, использование переменных экземпляра занимает более 1070 миллисекунд дольше, чем использование локальных переменных, и в два раза меньше утечек памяти. Причина, по которой я перешел от использования переменных local к экземпляру, заключается в том, что я использовал одни и те же данные в разных методах, поэтому использование переменной экземпляра имеет больше смысла, чем использование нескольких локальных переменных.

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

Код фрагмент:

public class DataActivity extends Activity { 

    //Raw value table entries 
    //Table 61 
    private int nbr_chns_set1; 
    private int nbr_blks_set1; 
    private int nbr_blk_ints_set1; 
    private int max_int_time_set1; 
    //Table 62 
    private int blk_end_read_flag; 
    private int blk_end_pulse_flag; 
    //Table 63 
    private int last_block_element; 
    private int nbr_valid_int; 
    private int nbr_valid_blocks; 
    private int interval_order; 
    //Table 64 
    ArrayList<String> table64Entries; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_lp_data); 

     initializeVariables(); 
     classMethods();  
    } 

    public void initializeVariables() { 

     //Populate class variables from values in Table 61 
     TableReader tableReader = new TableReader(this, R.raw.table61); 
     ArrayList<String> table61Entries = tableReader.readTable(); 
     nbr_chns_set1 = table61Entries.get(98); 
     nbr_blks_set1 = table61Entries.get(90); 
     nbr_blk_ints_set1 = table61Entries.get(94); 
     max_int_time_set1 = table61Entries.get(102); 
     blk_end_read_flag = table61Entries.get(22); 
     blk_end_pulse_flag = table61Entries.get(26); 

     //Populate class variables from values in Table 63 
     tableReader = new TableReader(this, R.raw.table63); 
     ArrayList<String> table63Entries = tableReader.readTable(); 
     last_block_element = table63Entries.get(38); 
     nbr_valid_int = table63Entries.get(5)); 
     nbr_valid_blocks = table63Entries.get(34); 
     interval_order = table63Entries.get(22); 

     //Populate class variables from values in Table 64 
     tableReader = new TableReader(this, R.raw.table64); 
     table64Entries = tableReader.readTable(); 

    } 

    public void classMethods() { 
     ... 
    } 
+0

Некоторые замечательные ответы в этой теме, связанные с вашим вопросом, но они напрямую не говорят о воздействии одного или другого на производительность: http://stackoverflow.com/questions/1794141/java-instance-variables- vs-local-variables –

+0

Вы получаете ошибки из памяти – Raghunandan

+0

Нет ошибок. Когда я сказал «утечки памяти», я имел в виду количество раз, когда LogCat записывал «GC_CONCURRENT», освобождая память. – McLovin

ответ

2

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

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

http://www.youtube.com/watch?v=_CruQY55HOk. Разговор об управлении памятью.

http://developer.android.com/training/articles/perf-tips.html.

+0

Закрыть. Локальные * примитивные * переменные находятся в стеке. Объекты всегда создаются в куче. Кроме того, сбор мусора не работает на стек. Когда метод выходит, указатель стека просто сбрасывается, «отбрасывая» кадр стека. – Simon

+0

@Simon я отредактировал свой ответ. Сброс указателя означает, что стек очищается, выбирая элементы. Когда метод заканчивает переменную – Raghunandan

+0

Элементы не выгружаются. Когда метод вводится, текущий указатель стека сохраняется. Затем метод выделяет память в стеке. Когда метод выходит, предыдущий указатель стека значение восстанавливается, поэтому освобождение всего кадра стека за одну операцию. – Simon