1

我似乎在 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();
        }
    }

}
4

1 回答 1

2

问题是程序生成的输出量。如果 Eclipse 试图将其全部存储在输出控制台中,它将耗尽内存。

于 2013-08-08T09:58:27.663 回答