Ответ 1
В Java/Android переменная или константа static
не будет собираться мусором. Он просто остается там, когда класс, который его удерживает, загружается через загрузчик классов. Класс-загрузчик afaik всегда одинаковый для всех классов внутри вашего приложения, а тот, который имеет статические ссылки на все ваши классы (например, MyInnerClass.class
). Так как загрузчик классов не уходит, ваши классы не будут делать это ни с тех пор, как они ссылаются, а потому не собирают мусор.
Как в вашем примере
public class SomeClass extends SurfaceView {
private static Context myContext;
public MyInnerClass(Context context){
myContext = context; // This is bad.
}
}
Это действительно плохо. Даже если не существует ссылки на SomeClass
(например, Activity
, который показал, что ваш пользовательский SurfaceView
закончился), статическая ссылка на Context
(и любая другая переменная/константа static
в SomeClass
останется. Вы можете считать, что все они просочились, поскольку сбор мусора невозможен, т.е. Context
и т.д. Если у вас есть регулярная ссылка на переменную, то после того, как экземпляр, содержащий эту переменную, больше не ссылается на него, весь экземпляр, включая его ссылки на другие вещи могут и будут собираться мусором. Java может даже обрабатывать круговые ссылки в порядке.
Для констант, которые вы хотите, чтобы это произошло, и обычно это плохо, поскольку количество констант и объем памяти, которые они занимают, невелики. Также константы не должны (не должны) ссылаться на другие экземпляры, которые занимают большие объемы памяти, такие как Context
или Bitmap
.
Помимо возможности создавать утечки памяти через статические переменные, вы также можете создавать проблемы, если вы не хотите иметь только одну вещь для всех экземпляров одновременно. Например, если вы сохранили Bitmap
вашего SurfaceView
в переменной static
, у вас не может быть двух разных изображений. Даже если два SurfaceView
не отображаются одновременно, вы можете столкнуться с проблемами, поскольку каждый новый экземпляр, вероятно, перезапишет старое изображение, и если вы вернетесь к другому SurfaceView
, вы неожиданно увидите неправильное изображение. Я почти уверен, что вы не хотите использовать static
здесь.
Тот факт, что ваш внутренний класс является static class
, не означает, что вам нужно использовать статические переменные - это просто означает, что он ведет себя как метод static
, поскольку он не может использовать переменные экземпляра (те, которые не являются static
) в вашем классе.
Чтобы избежать утечек памяти, вы просто не должны использовать статические переменные вообще. Нет необходимости использовать их, если вы не делаете специальные материалы (например, подсчет экземпляров класса). Константы в порядке.