Утечка памяти в Java? Обеденные философы реализованы с помощью семафоров
Кажется, я создал утечку памяти в Java, что даже не осознавал, что это возможно. Я реализовал одно решение проблемы параллелизма столовых философов на основе рисунка из книги Эндрю Таненбаума " Современные операционные системы".
Он отлично работает, если не блокировать и не блокировать потоки. Однако... за довольно короткий промежуток времени он израсходовал около 1 ГБ ОЗУ (на основе наблюдения за системными ресурсами 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();
}
}
}
1 ответ
Решение
Проблема заключается в количестве выходных данных, генерируемых программой. Eclipse исчерпает память, если попытается сохранить все это в консоли вывода.