Являются ли примитивные типы мусора, собранные в Android?

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

В настоящее время я сокращаю каждое отдельное выделение, которое я могу из одной из моих игр, чтобы уменьшить частоту сбора мусора и воспринимаемое "отставание", поэтому для каждой переменной, которую я создаю, является объект (String и Rect for пример) Я уверен, что я создаю его перед обработкой в ​​своем конструкторе и не создаю временные переменные в простых 10 линейные функции... (надеюсь, это имеет смысл)

В любом случае я работал, хотя сейчас еще немного, и понял, что могу ошибаться в своем предположении о сборке мусора и примитивных типах (int, boolean, float) - эти примитивные переменные типа, которые я создаю в 10-строчной функции который называется 20 раз в секунду добавляя к моей проблеме сбор мусора?

Итак, год назад каждые несколько секунд я видел сообщение в logcat, например

GC освободил 4010 объектов /484064 байт в 101ms

Теперь я вижу это сообщение каждые 15-90 секунд или около того...

Итак, чтобы перефразировать мой вопрос: включены ли примитивные типы (int, float, boolean и т.д.) при просмотре этого сообщения?

Ответы

Ответ 1

Примитивные типы не являются объектами, поэтому они не вызывают сбор мусора. Тем не менее, вы должны быть очень осторожны, потому что из-за бокса примитивный тип может легко стать объектом, если вы явно не сделаете этого.

Например, если вы хотите использовать целые ключи HashMap < > , вы должны использовать HashMap. Обратите внимание, что поскольку "int" не является объектом, его нельзя использовать в контейнере. Integer - это объектная версия примитива int. Когда вы пишете такой код, для вас автоматически будет создан объект Integer:

HashMap<Integer, Object> map = new HashMap<Integer, Object>();
int someNum = 12345;    // no object created.
map.put(someNum, null); // Integer object created.

Обратите внимание, что то же самое произойдет, если вы не используете дженерики, но еще более скрыты:

HashMap map = new HashMap();
int someNum = 12345;    // no object created.
map.put(someNum, null); // Integer object created.

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

Ответ 2

Кажется, ответ отрицательный. Похоже, что примитивы помещаются в стек в Java, а не в кучу, и только объекты собирают мусор. Я нашел много коротких ссылок на это, проверьте Википедию. Для немного более тяжелого чтения см. Статью о реализации коллекции мусора JVM, которая объясняет немного более однозначно, что примитивы хранятся в физически отдельных ячейках памяти, поэтому они не ошибочно включены в сборку мусора . Если вам кажется, что скимминг, страница 4, где это объясняется наиболее непосредственно.

Вот специфические темы для Android, в которых gc только сканирует указатели и как он проверяет, что

Ответ 3

[Примечание: у меня пока нет полных комментариев, поэтому я добавляю это как отдельный ответ.]

Похоже, что примитивы стек в Java, а не в куче и только объекты - мусор собраны.

Это не совсем точно. Примитивы могут храниться в локальных переменных, а также как статические или экземплярные поля классов. В последнем случае они действительно хранятся в куче, но они, как важно, не имеют "собственной жизни" и, в частности, не отдельно от объекта, в котором они содержатся.

Android не запускает стандартный основанная на стеке JVM, у нее есть своя на основе регистров.

Это истинное утверждение, но оно также немного вводит в заблуждение и относится к первому вопросу. Фактически, когда один метод вызывает другой (и так далее), кадры активации этих методов хранятся в стеке в реализации Dalvik. Разница в том, что при обращении к кадру активации в отдельности кадры активации Dalvik не содержат в себе стека переменных размеров. В этом отношении способ, которым Dalvik организует кадры активации, больше похож на то, как они обрабатываются для традиционных C-подобных языков (таких как C или С++).