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