【问题标题】:Memory leak in Java? Dining philosophers implemented with SemaphoresJava中的内存泄漏?用信号量实现的餐饮哲学家
【发布时间】: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


【解决方案1】:

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

【讨论】:

  • 再次感谢。很惊讶我以前从未遇到过这种情况,因为我喜欢创建大量愚蠢的输出来测试长时间运行的程序!
  • 不客气 :-) 这是一个有点疯狂的猜测,因为我已经为输出缓冲区设置了限制,所以我也没有看到它,但实际上没有任何东西可以泄漏所以我不得不看日食。
猜你喜欢
  • 2010-10-11
  • 2016-03-04
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
  • 2014-04-11
  • 1970-01-01
相关资源
最近更新 更多