Java中的内存泄漏?与Semaphores一起实施的餐饮哲学家

时间:2013-08-08 09:30:37

标签: java concurrency memory-leaks semaphore dining-philosopher

我似乎在Java中创建了一个内存泄漏,我甚至没有意识到这是可能的。我根据Andrew Tanenbaum的书“现代操作系统”中的一个人物,为餐饮哲学家并发问题实施了一个解决方案。

只要没有死锁并且不会使任何线程挨饿,它都能正常工作。但是......在相当短的时间内它会占用大约1GB的RAM(基于观看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 个答案:

答案 0 :(得分:2)

问题是程序生成的输出量。如果Eclipse试图将所有内容保存在输出控制台中,Eclipse将耗尽内存。