Утечка памяти в Java? Обеденные философы реализованы с помощью семафоров

Кажется, я создал утечку памяти в Java, что даже не осознавал, что это возможно. Я реализовал одно решение проблемы параллелизма столовых философов на основе рисунка из книги Эндрю Таненбаума " Современные операционные системы".

Он отлично работает, если не блокировать и не блокировать потоки. Однако... за довольно короткий промежуток времени он израсходовал около 1 ГБ ОЗУ (на основе наблюдения за системными ресурсами Windows), а затем Eclipse вылетает с сообщением Unhandled event loop exception Java heap space,

Вопросы:

  • Чем это вызвано?
  • Какие инструменты (кроме логического вывода, который меня подводит) я мог бы использовать, чтобы ответить на этот вопрос сам? Java/ профилирование памяти и т. Д.? У меня нет опыта работы с такими инструментами вне отладчика, встроенного в Eclipse.

SSCCE:

import java.util.concurrent.Semaphore;

public class SemaphoreDiningPhilosophers {

    static enum State {
        THINKING,
        HUNGRY,
        EATING
    }

    static int N = 5;

    static Semaphore mutex;
    static Semaphore[] sem_philo;
    static State[] states;

    static void philosopher(int i) throws InterruptedException {
        states[i] = State.THINKING;
        System.out.println("Philosopher #" + (i + 1) + " is thinking.");

        while (true) {
            takeForks(i);
            eat(i);
            putForks(i);
        }
    }

    static void takeForks(int i) throws InterruptedException {
        mutex.acquire();
        states[i] = State.HUNGRY;
        test(i);
        mutex.release();
        sem_philo[i].acquire();
    }

    static void eat(int i) {
        System.out.println("Philosopher #" + (i + 1) + " is eating.");
    }

    static void putForks(int i) throws InterruptedException {
        mutex.acquire();
        states[i] = State.THINKING;
        System.out.println("Philosopher #" + (i + 1) + " is thinking.");
        test((i + 4) % N);
        test((i + 1) % N);
        mutex.release();
    }

    static void test(int i) {
        if (states[i] == State.HUNGRY
                && states[(i + 4) % N] != State.EATING
                && states[(i + 1) % N] != State.EATING) {
            states[i] = State.EATING;
            sem_philo[i].release();
        }
    }

    public static void main(String[] args) {

        mutex = new Semaphore(1);
        sem_philo = new Semaphore[N];
        for (int i = 0; i < N; i++) {
            sem_philo[i] = new Semaphore(0);
        }
        states = new State[N];

        Thread[] philosophers = new Thread[N];
        for (int i = 0; i < N; i++) {
            final int i2 = i;
            philosophers[i2] = new Thread(new Runnable() {
                public void run() {
                    try {
                        philosopher(i2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            philosophers[i2].start();
        }
    }

}

1 ответ

Решение

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

Другие вопросы по тегам