У меня есть этот существующий API, работающий в l oop, который создает соединение и извлекает огромные json (1 ГБ) в каждой итерации из службы через restTemplate следующим образом:
ResponseEntity<String> response = restTemplate.exchange(uri.get().toString(), HttpMethod.POST,entity,
String.class);
Ответ затем преобразуется в сложный java объект через GSON. Проблема с вышеприведенным подходом состоит в том, что шаблон rest преобразует входной поток в String через StringBuffer, что приводит к созданию большого количества символов char [], которые в конечном итоге исчерпывают память (OOM), когда l oop повторяется слишком долго, что обычно имеет место. Вместо RestEntity я даже использовал HttpClient, он тоже делает то же самое (расширяет массив символов).
Чтобы решить проблему с OOM, я реорганизовал API для потоковой передачи данных в файл. Создание временного файла в каждой итерации и преобразование в объекты следующим образом:
File targetFile = new File("somepath\\response.tmp");
FileUtils.copyInputStreamToFile(response.getEntity().getContent(), targetFile);
List<Object> objects = gson.fromJson(reader, new TypeToken<List<Object>>(){}.getType());
Это путь к go или есть какой-нибудь эффективный подход для решения таких проблем? Может быть, пул соединений вместо создания новых в каждой итерации (это будет значительным изменением?)
Кроме того, при анализе API для кучи 4 ГБ xmx, 2 ГБ xms, jvisual показывает следующее:
![enter image description here](https://i.stack.imgur.com/WiJvw.png)
Как видно, запущенному потоку выделены огромные байты.
Размер кучи во время выполнения API:
![enter image description here](https://i.stack.imgur.com/sAwZk.png)