Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / ForkJoinPool пример - обсудим ? / 5 сообщений из 5, страница 1 из 1
15.05.2018, 14:12
    #39645007
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ForkJoinPool пример - обсудим ?
Нашел на просторах интернета пример:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
// https://examples.javacodegeeks.com/core-java/util/concurrent/recursivetask/java-util-concurrent-recursivetask-example/

package javaUtil.concurrent.executors.ExecutorService;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class ForkJoinPoll_RecursiveTask {

	private static final int SIZE = 100000000; // При малом значении этой переменной у меня получался лучший результат при последовательном вычислении.

	public static void main(String[] args) {

		final int[] numbers = new int[SIZE];
		int maxNum = 0;

		// Start sequential calculation
		long st = System.currentTimeMillis();

		for (int i = 0; i < SIZE; i++) {
			numbers[i] = (int) (Math.random() * 10000);
			if (numbers[i] > maxNum) {
				maxNum = numbers[i];
			}
		}

		System.out.println("Calculated maximum number (sequential execution): " + maxNum + " -- Total time: " + (System.currentTimeMillis() - st));

		// Start parallel calculation
		long pt = System.currentTimeMillis();

		ForkJoinPool pool = new ForkJoinPool(4);
		MaxNumberCalculator fbn = new MaxNumberCalculator(numbers);
		System.out.println("Calculated maximum number (parallel execution): " + pool.invoke(fbn) + " -- Total time: " + (System.currentTimeMillis() - pt));
	}
	
	
	@SuppressWarnings("serial")
	static class MaxNumberCalculator extends RecursiveTask<Integer> {

	    public static final int THRESHOLD = 5;
	    private int[] numbers;
	    private int start;
	    private int end;

	    public MaxNumberCalculator(int[] numbers) {
	        this(numbers, 0, numbers.length);
	    }

	    public MaxNumberCalculator(int[] numbers, int start, int end) {

	        this.numbers = numbers;
	        this.start = start;
	        this.end = end;
	    }

	    @Override
	    public Integer compute() {
	        int length = end - start;
	        int max = 0;
	        
	        if (length < THRESHOLD) {
	            for (int x = start; x < end; x++){
	                    max = numbers[x];
	            }
		        return max;
	        } else {
	            int split = length / 2;
	            MaxNumberCalculator left = new MaxNumberCalculator(numbers, start, start + split);
	            left.fork();
	            MaxNumberCalculator right = new MaxNumberCalculator(numbers, start + split, end);
	            return Math.max(right.compute(), left.join());
	        }
	    }
	}
}



При попытке запуска этого примера на своем компьютере словил Throwable:
Код: java
1.
2.
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at javaUtil.concurrent.executors.ExecutorService.ForkJoinPoll_RecursiveTask.main(ForkJoinPoll_RecursiveTask.java:14)



После чего уменьшил значение переменной SIZE на порядок (убрал один 0). Результат выполнения:
Код: java
1.
2.
Calculated maximum number (sequential execution): 9999 -- Total time: 516
Calculated maximum number (parallel execution): 9999 -- Total time: 297



убрал еще один 0:
Код: java
1.
2.
Calculated maximum number (sequential execution): 9999 -- Total time: 47
Calculated maximum number (parallel execution): 9999 -- Total time: 63


ну и дальше растет разница в скорости вычисления в стору последовательного исполнения.

Здесь вроде как пропущен 1 if в методе compute, но суть не в этом. Меня интересуют 2-а вопроса:
1). Кто съел всю память ? - потоки ?
2). Если задача и порожденные ею подзадачи занимаются только вычислениям, без задержек (например, чтение данных из базы, ожидания ввода и прочего) и тп, то оптимальное количество потоков для такой задачи = количество процессоров*количество ядер в них ?
...
Рейтинг: 0 / 0
15.05.2018, 14:21
    #39645016
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ForkJoinPool пример - обсудим ?
Примечание: В отличии от оригинального примера класс, реализующий RecuriveTask, я сделал статическим и поместил внутрь основного.
...
Рейтинг: 0 / 0
15.05.2018, 14:43
    #39645031
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ForkJoinPool пример - обсудим ?
Про память сразу не посмотрел, ругается на строку -
Код: java
1.
final int[] numbers = new int[SIZE];

, хотя SIZE < Integer.MAX_VALUE, буду разбираться ...
...
Рейтинг: 0 / 0
15.05.2018, 16:21
    #39645108
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ForkJoinPool пример - обсудим ?
Вроде разобрался (взял примерное значение размера массива, после которого вылетал OutOfMemoryError, равным 44 700 000 элементов;):
В системе 3.41 Гб ОЗУ.
до создания массива команда Runtime.getRuntime().freeMemory() до выдает значение 15 775 784 байт.
для выделения памяти массиву потребуется 44 700 000 * 4 = 178 800 000 байт.

Мое предположение: Так как объем памяти, необходимый для выделения массиву превышает объем свободной памяти, то скорее всего JVM резервирует дополнительную память (возможно вместе с чисткой мусора). При этом максимальное значение выделяемой памяти не может превышать какого то порогового значения (подозреваю, что это 256 мб), после которого и ловим error.

Кто в теме, напишите, прав ли я? И может посоветуете хорошие доки по теме?

Примечание: после распределения 44 700 000 элементов команда Runtime.getRuntime().freeMemory() до выдает значение 5 038 528 байт.
...
Рейтинг: 0 / 0
15.05.2018, 16:28
    #39645113
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ForkJoinPool пример - обсудим ?
IMHO

Параметры командной строки Java
-Xmx -Xms
указывать явно и крайне желательно равными друг другу

в остальных случаях, за доп. памятью обрашаемся к ОС, а почему она не смогла выделить, вопрос уже к ОС )))
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / ForkJoinPool пример - обсудим ? / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]