Понимание размеров кучи в Android

Я новичок в разработке для Android и, похоже, не могу понять Java Out of Memory. исключение. Я знаю, что это означает, что мое приложение превысило бюджет виртуальной машины, но после многократных поисков в Google я все еще не понимаю эту концепцию. Я боюсь, что мое приложение использует слишком много памяти, потому что у меня есть шесть селекторов кнопок на экран с двумя растровыми изображениями для каждого селектора, каждый из которых составляет около 20 КБ в соответствии с вкладкой свойств. На моем корневом G2x я установил бюджет виртуальной машины на 12 МБ, перезагрузил телефон и запустил приложение без каких-либо проблем. Я отвязываю чертежи для каждого onDestroy() и намекаю на то, что GC также будет работать здесь. После некоторого использования приложения в эмуляторе я нажимаю «Вызвать GC» на экране DDMS, и результаты ID=1, размер кучи 6,133 МБ, выделено 2,895 МБ, свободно 3,238 МБ, % использования 47,20, # объектов 52 623.

Здесь я не понимаю, что происходит, мой эмулятор настроен на 24 МБ виртуальной машины. Где этот номер? Фактическая проблема, с которой я сталкиваюсь, заключается в том, что если я установлю эмулятор на 16 МБ виртуальной машины, мое приложение выйдет из строя во втором действии с исключением Out of Memory. Почему он не зависает на моем телефоне с установленной виртуальной машиной 12 МБ или на моем старом телефоне HTC Magic с 12 МБ виртуальной памяти? Также вы, ребята, думаете, что мое приложение занимает слишком много памяти? Я понятия не имею, хороши ли эти числа DDMS или нет. Спасибо за ваше время.

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

@Override
protected void onDestroy() {
    super.onDestroy();

    unbindDrawables(findViewById(R.id.myRootLayout));
    System.gc();
}

private void unbindDrawables(View view) {
    if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
    }
    if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
        }
        ((ViewGroup) view).removeAllViews();
    }
}

В противном случае все, что я делаю, это добавляю onClickListeners к кнопкам с фоном PNG. Я хотел бы узнать, как программно указывать фон кнопки, но мне нужно иметь функции выбора, такие как фокус, нажатие, не сфокусированный, но нажатый и т. д., чтобы фон кнопки менялся в соответствии с взаимодействием с пользователем. Я просмотрел документацию по этому поводу, но она кажется ошеломляющей, поэтому я решил начать здесь с основ управления кучами и перейти к указанию селекторов в коде. Это может не иметь смысла, но есть ли «здоровый» объем памяти, который приложение может выделить, не приближаясь к исключению «Недостаточно памяти»? Например, если приложение выделило 6 МБ, все должно быть в порядке, но 8 МБ будут толкать его, есть ли такие ограничения в распределении памяти? Еще раз спасибо, Алекс Локвуд, за ваш ответ. Я собираюсь читать и перечитывать его снова, пока этот материал не станет для меня понятным

30
задан Simon Schubert 8 June 2016 в 11:42
поделиться