我似乎在Java中创建了一个内存泄漏,我甚至没有意识到这是可能的。我根据Andrew Tanenbaum的书“现代操作系统”中的一个人物,为餐饮哲学家并发问题实施了一个解决方案。
只要没有死锁并且不会使任何线程挨饿,它都能正常工作。但是......在相当短的时间内它会占用大约1GB的RAM(基于观看Windows系统资源),然后Eclipse崩溃并显示消息Unhandled event loop exception
Java heap space
。
问题:
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();
}
}
}
答案 0 :(得分:2)
问题是程序生成的输出量。如果Eclipse试图将所有内容保存在输出控制台中,Eclipse将耗尽内存。