Где утечка памяти для этого HashMap? - PullRequest
4 голосов
/ 21 июня 2019

Мне нужно определить, где в этом коде утечка памяти

Я не знаю, что попробовать

Мое подозрение - утечка памяти в HashMap при получении новых ресурсов, но я не совсем уверен

public class Runner {
    private HashMap<Integer, Resource> resources = new HashMap<Integer, Resource>();

    public Iterable<Resource> getResources() {
        return this.resources.values();
    }

    public Resource acquireResource(int id) {
        Resource w = this.resources.get(id);
        if (w == null) {
            w = new Resource(id);
            this.resources.put(id, w);
        }

        return w;
    }

    public void releaseResource(int id) {
        Resource w = this.resources.getOrDefault(id, null);
        if (w == null)
            throw new IllegalArgumentException();

        w.dispose();
    }

    public static void main(String[] args) {
        Runner d = new Runner();

        d.acquireResource(1).performTask("Task11");
        d.acquireResource(2).performTask("Task21");
        System.out.println(String.join(", ", d.acquireResource(2).getTasks()));
        d.releaseResource(2);
        d.acquireResource(1).performTask("Task12");
        System.out.println(String.join(", ", d.acquireResource(1).getTasks()));
        d.releaseResource(1);
    }

    public class Resource {
        private ArrayList<String> tasks = new ArrayList<String>();

        private int id;

        public int getId() {
            return this.id;
        }

        public Iterable<String> getTasks() {
            return this.tasks;
        }

        public Resource(int id) {
            this.id = id;
        }

        public void performTask(String task) {
            if (this.tasks == null)
                throw new IllegalStateException(this.getClass().getName());

            this.tasks.add(task);
        }

        public void dispose() {
            this.tasks = null;
        }
    }
}

Есть какая-то утечка памяти, я не знаю, что

Ответы [ 2 ]

4 голосов
/ 21 июня 2019

Вы не удаляете какие-либо записи с карты, и, следовательно, теоретически она может расти бесконечно. Вам, вероятно, следует вызвать resources.remove(id) вместо resources.getOrDefault(id, null), потому что, хотя первый фактически удаляет запись, последний не делает.

1 голос
/ 21 июня 2019

Вы не высвобождаете все ресурсы, которые приобрели.Давайте рассмотрим main, которым вы поделились:

d.acquireResource(1).performTask("Task11");
d.acquireResource(2).performTask("Task21");
System.out.println(String.join(", ", d.acquireResource(2).getTasks()));
d.releaseResource(2);

// 1 is acquired again, without relesaing the first 1 you acquired
d.acquireResource(1).performTask("Task12");
System.out.println(String.join(", ", d.acquireResource(1).getTasks()));
d.releaseResource(1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...