Собираются ли примитивные типы мусора в Android? - PullRequest
16 голосов
/ 19 марта 2010

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

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

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

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

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

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

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

Ответы [ 3 ]

25 голосов
/ 19 марта 2010

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

Например, если вам нужен 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, который является контейнером примитивных целочисленных ключей.

6 голосов
/ 19 марта 2010

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

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

2 голосов
/ 06 мая 2011

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

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

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

Android не работает стандартно основанная на стеке JVM, она имеет свой собственный ВМ на основе регистра.

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

...