【发布时间】:2013-08-08 09:30:36
【问题描述】:
我似乎在 Java 中造成了内存泄漏,我什至没有意识到这是可能的。我根据 Andrew Tanenbaum 的Modern Operating Systems一书中的一个图,实现了哲学家就餐并发问题的一种解决方案。
只要没有死锁并且没有使任何线程饿死,它就可以正常工作。然而......在相当短的时间内它消耗了大约 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();
}
}
}
【问题讨论】:
-
在不知道确切的错误信息的情况下很难提供帮助。
-
@UwePlonus 对此感到抱歉...我能够复制它并获取文本,但非常无用:
Unhandled event loop exception Java heap space -
我猜 Eclipse 可能对程序创建的输出量有问题。 swt 中的某处可能存在泄漏。
-
@kiheru 这完全是一个太简单和显而易见的答案......而且它是正确的!哦,我应该想到的。在 Eclipse 首选项中找到了一个限制控制台输出的选项(显然我出于某种原因将其设置为无限制)。发布为答案,我会接受。 :-)
-
hrhr,我一直在想,因为循环中没有分配,我什至用visualvm 看了看,什么也看不到
标签: java concurrency memory-leaks semaphore dining-philosopher