Рубрики
Без рубрики

Эффективная Java: #7 Устаревший объект и утечка памяти

Java – это язык программирования сборщика мусора. Что это значит для вас? Я имею в виду, что язык… Помеченный как java, эффективная java, память.

Java – это язык программирования сборщика мусора. Что это значит для вас?

Я имею в виду, что язык позаботится об очистке неиспользуемых объектов в вашей программе. Если вы пришли с такого языка, как C/C++, вы почувствуете, что это похоже на сверхдержаву, потому что вам не нужно вручную очищать память для объектов, которые вы больше не используете (задача, о которой разработчик часто забывает).

Java сотворила волшебство с помощью своего алгоритма сборки мусора. В настоящее время их очень много но в основном он будет проверять наличие ссылки на выполняемую в данный момент программу с объектами, которые существуют в куче. Если есть какой-либо объект, на который программа не ссылалась, она очистит эти объекты, поскольку рассматривает их как мусор.

Давайте рассмотрим этот пример, который я взял из книги:

class PoolObjects {
   private static int DEFAULT_POOL_SIZE = 100;
   private int size = 0;
   private static Object[] pools;

   public PoolsObjects() {
      this.pools  = new Object[DEFAULT_POOL_SIZE];
   }

   public void add(Object o) {
      this.ensurePoolSize();
      this.pools[this.size++] = o;
   }

   public Object pop() {
      if (this.size == 0) {
         throw new EmptyPoolException();
      }
      Object r = this.pools[--size];
      return r;
   }

   private void ensurePoolCapacity() {
      if (this.pools.length = this.size) {
         this.pools = Arrays.copyOf(this.pools, 2 * size + 1);
   }
}

В приведенном выше примере есть очень тонкая точка утечки памяти. Как вы можете догадаться, по мере уменьшения размера массива элемент, индекс которого меньше значения size, будет неактивным или должен быть отброшен и очищен GC. Но на самом деле этого не будет, потому что на этот объект все еще ссылаются pools переменная.

Один из способов устранить проблему – обнулить элемент, на который больше не ссылались.

public Object pop() {
      if (this.size == 0) {
         throw new EmptyPoolException();
      }
      Object r = this.pools[--size];
      this.pools[size] = null; // Explicitly nulling out the element at size index.
      return r;
   }

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

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

Оригинал: “https://dev.to/htintrinh/effective-java-7-obsolete-object-and-memory-leak-n5o”