|
|
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Сижу- борюсь с outOfMemory. Диагноз стандартный char[]. Суть задачи - распарс текстового файла. Каждая строка храниться в HashMap(строка маппится по полям на экземпляр класс сущности некой). Сам файл huge!!!(боле нескольки гигов в gz) Последовательность примерно такая: readLine->parseLine->entityMapper->entityToCache. Кроме кэша все переменные - локальные. Читаю разнообразные GC типсы..но судя по всему - они по факту бесполезны. 1. Кто как эффективно боролся?:) 2. System.arraycopy(src, 0, dst, 0, src.length) - может ли подобная операция(над каждой строкой выполняется) привести к подобным последствия? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:11:12 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
ОзверинСуть задачи - распарс текстового файла. Каждая строка храниться в HashMap(строка маппится по полям на экземпляр класс сущности некой). Сам файл huge!!!(боле нескольки гигов в gz) Давайте не углублятся в детали, а просто логически подумаем. Есть текстовый файл в несколько гигов. Его нужно распарсить в более сложную структуру. Соответственно новая структура легко занимает 3-4 гига. При чем здесь тогда вообще GC? Что именно нужно сделать с этим объемом данных? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:16:03 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
BlazkowiczОзверинСуть задачи - распарс текстового файла. Каждая строка храниться в HashMap(строка маппится по полям на экземпляр класс сущности некой). Сам файл huge!!!(боле нескольки гигов в gz) Давайте не углублятся в детали, а просто логически подумаем. Есть текстовый файл в несколько гигов. Его нужно распарсить в более сложную структуру. Соответственно новая структура легко занимает 3-4 гига. При чем здесь тогда вообще GC? Что именно нужно сделать с этим объемом данных? я это понимаю. Каждая строка содержит ключ, по которому нужно агрегировать данные, т.е весь объем данных нужен, чтобы вычислить некие величины. Если НЕ брать в расчет возможность хранения "временных" данных в бд, то есть ли tips для подобных задач?;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:20:44 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Озверин, mapreduce. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:23:11 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Озвериня это понимаю. А я нет. Какая конечная цель? Какой результат парсинга? Что на выходе? ОзверинКаждая строка содержит ключ, по которому нужно агрегировать данные, т.е весь объем данных нужен, чтобы вычислить некие величины. Если НЕ брать в расчет возможность хранения "временных" данных в бд, то есть ли tips для подобных задач?;) Нужно типа статистику посчитать по всем данным? Надо от задачи отталкиваться. Почему вы решили что OutOfMemoryError связан с работой GC, а не с банальной нехваткой памяти? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:24:28 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Либо хранить в ehcache и разрешить ему записывать данные на диск. Еще, похоже, есть вариант память перед CPU. Если задача позволяет, можно делать так. Находим первый ключ, обрабатываем все строки, для которых он нужен. Запоминаем его и находим второй ключ. И т.д. Минус в том, что файл будет прочитан столько раз, сколько у вас ключей. Плюс в том, что если ключей много, то нагрузка на память будет существенно меньше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:25:36 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
BlazkowiczОзвериня это понимаю. А я нет. Какая конечная цель? Какой результат парсинга? Что на выходе? ОзверинКаждая строка содержит ключ, по которому нужно агрегировать данные, т.е весь объем данных нужен, чтобы вычислить некие величины. Если НЕ брать в расчет возможность хранения "временных" данных в бд, то есть ли tips для подобных задач?;) Нужно типа статистику посчитать по всем данным? Надо от задачи отталкиваться. Почему вы решили что OutOfMemoryError связан с работой GC, а не с банальной нехваткой памяти? На выходе - расчет статистики. 1. задача - это расчет статистики 2. задача - баланс между выделения памяти под heap size, т.е - чем меньше, тем лучше ;) На данный момент я под задачу выделил 1200m. Над каждой строкой примерно следующие операции выполняются: String readLine() String[] parse(String line) MyEntity createEntity(String[] line) //логика примерно такая, если объект по ключу уже есть в кэше, расчитываем некие величиные его полей, если нет - в мапу кидаем просто) void cacheMyEntity()->hashMap void groupMyEntity()-hashMap ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:29:59 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
LeonidvЛибо хранить в ehcache и разрешить ему записывать данные на диск. Еще, похоже, есть вариант память перед CPU. Если задача позволяет, можно делать так. Находим первый ключ, обрабатываем все строки, для которых он нужен. Запоминаем его и находим второй ключ. И т.д. Минус в том, что файл будет прочитан столько раз, сколько у вас ключей. Плюс в том, что если ключей много, то нагрузка на память будет существенно меньше. Файл в запакованном виде 4 гига. Боюсь соврать, там вроде 27 миллионов записей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:32:42 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Озверин, колись и не стесняйся лохануться. Просто нужен свежий взгляд. 95 процентов всех причин - простые (с - статистика авиапроисшествий). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:32:55 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
ОзверинLeonidvЛибо хранить в ehcache и разрешить ему записывать данные на диск. Еще, похоже, есть вариант память перед CPU. Если задача позволяет, можно делать так. Находим первый ключ, обрабатываем все строки, для которых он нужен. Запоминаем его и находим второй ключ. И т.д. Минус в том, что файл будет прочитан столько раз, сколько у вас ключей. Плюс в том, что если ключей много, то нагрузка на память будет существенно меньше. Файл в запакованном виде 4 гига. Боюсь соврать, там вроде 27 миллионов записей. Не уловил связи между этой информацией и моим ответом :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:34:28 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Почему вы решили что OutOfMemoryError связан с работой GC, а не с банальной нехваткой памяти? Строки имеют свойство переиспользовать char[], при, например substring().Не получается ли так что String[] у вас все экземпляры ссылаются на String целой строки, которую вы считали? В MyEntity много строк? Почему был выбран подход чтения строками, а не потоком символов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:34:43 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Petro123Озверин, колись и не стесняйся лохануться. Просто нужен свежий взгляд. 95 процентов всех причин - простые (с - статистика авиапроисшествий). Так а чего колоться? Я сижу туплю...спрашивайте ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:34:46 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
BlazkowiczПочему вы решили что OutOfMemoryError связан с работой GC, а не с банальной нехваткой памяти? Строки имеют свойство переиспользовать char[], при, например substring().Не получается ли так что String[] у вас все экземпляры ссылаются на String целой строки, которую вы считали? В MyEntity много строк? Почему был выбран подход чтения строками, а не потоком символов? Насчет CG - нельзя же себя ругать, поругал его ) Не получается ли так что String[] у вас все экземпляры ссылаются на String целой строки, которую вы считали? разумно. Сейчас будем смотреть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:37:32 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
На сколько сложно отказатся от String в пользу char[] и CharSequence? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:39:21 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
LeonidvОзверин, mapreduce. Вот правильный ответ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:45:53 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Большой Синий КитLeonidvmapreduce. Вот правильный ответ. Обоснуй. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:47:18 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Записей очень много. Производить конечный расчет можно только имея все записи распарсенными. Загрузить их все в виде объектов не получается - очень много памяти. То есть нужно уменьшить количество записей, которые нужно распарсить. Остается только одно - mapreduce. Честно говоря, ничего другого, на мой взгляд, нету. Синхронно производить обработку этих данных для получения их в более компактной форме, или нет - это уже неважно. Но идея именно в этом. А это мапредьюс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:53:59 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Blazkowicz В MyEntity много строк? По сути myEntity - это одна строка. String[] values myEntity.setColumn0(values[0]); myEntity.setColumn1(values[1]); myEntity.setColumn2(values[2]); myEntity.setColumnN(values[N]); Но. Для примера ключ1, поле1=1, поле2=10 ключ1, поле1=2, поле2=10 ключ1, поле1=5, поле2=15 если у строк ключ совпадает, то мы просто в 1ой сущности суммируем поле1 и поле2, т.е. не факт, что каждая новая строка создат и кинет в кэш новую сущность ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:56:55 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
ОзверинBlazkowicz В MyEntity много строк? По сути myEntity - это одна строка. String[] values myEntity.setColumn0(values[0]); myEntity.setColumn1(values[1]); myEntity.setColumn2(values[2]); myEntity.setColumnN(values[N]); Но. Для примера ключ1, поле1=1, поле2=10 ключ1, поле1=2, поле2=10 ключ1, поле1=5, поле2=15 если у строк ключ совпадает, то мы просто в 1ой сущности суммируем поле1 и поле2, т.е. не факт, что каждая новая строка создат и кинет в кэш новую сущность Ну вот, мапредьюс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:57:58 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
ОзверинПо сути myEntity - это одна строка. если у строк ключ совпадает, то мы просто в 1ой сущности суммируем поле1 и поле2, т.е. не факт, что каждая новая строка создат и кинет в кэш новую сущность Какая длина строки и сколько уникальных по ключу сущностей в файле? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 16:58:33 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Большой Синий Кит, а почему БД не подходит: - сливаем сырые данные - в фоне достаём - обработал - положил ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:00:13 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Petro123Большой Синий Кит, а почему БД не подходит: - сливаем сырые данные - в фоне достаём - обработал - положил ? Почему не подходит? Подходит, согласен. Просто тут ведь нет в исходных данных БД... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:01:40 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Petro123Большой Синий Кит, а почему БД не подходит: - сливаем сырые данные - в фоне достаём - обработал - положил ? Импортируем в MySQL. Пишем SQL запрос. Profit! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:03:10 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
BlazkowiczОзверинПо сути myEntity - это одна строка. если у строк ключ совпадает, то мы просто в 1ой сущности суммируем поле1 и поле2, т.е. не факт, что каждая новая строка создат и кинет в кэш новую сущность Какая длина строки и сколько уникальных по ключу сущностей в файле? Длина строки сильно варьироваться может. Условно мы говорим о 1500 символах в строке. (примерно такой порядок) Насчет кол-ва сущностей, очень трудно сказать. 1 уникальный ключ на строку - может быть >1 уникального ключа на строку - тоже(работаю с логом стороннего разработчика, за что купил, как говорится) <1 уникального ключа на строку - если она будет агрегирована с предыдущими строками ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:03:32 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
BlazkowiczPetro123Большой Синий Кит, а почему БД не подходит: - сливаем сырые данные - в фоне достаём - обработал - положил ? Импортируем в MySQL. Пишем SQL запрос. Profit! я честно сказать первым делом предложил именно этот вариант. Но "начальство" сверху сильно меня ограничило ;) я как бе заметил, что для агрегирования большого кол-ва даанных бд и созданы..но там что то с ресурсами сервака и одновременной работой нескольих таких паресров. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:05:02 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Большой Синий КитPetro123Большой Синий Кит, а почему БД не подходит: - сливаем сырые данные - в фоне достаём - обработал - положил ? Почему не подходит? Подходит, согласен. Просто тут ведь нет в исходных данных БД... Есть сходные задачи: 5000 датчиков льют данные. Их надо обработать. - пишем быстро - не торопясь обрабатываем. Главное что статистика не оперирует сразу ВСЕМИ - тогда можно в ОРМ - если сразу всеми, тогда SQL операторы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:07:22 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
просто у БД память GC не кончается ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:08:19 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Petro123, :) Согласен ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:09:40 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
ОзверинДлина строки сильно варьироваться может. Условно мы говорим о 1500 символах в строке. (примерно такой порядок) Насчет кол-ва сущностей, очень трудно сказать. 1 уникальный ключ на строку - может быть >1 уникального ключа на строку - тоже(работаю с логом стороннего разработчика, за что купил, как говорится) <1 уникального ключа на строку - если она будет агрегирована с предыдущими строками Теперь я озадачен, чуть более чем полностью. Имеем 4Гб упакованый файл (zip). Можно предположить что после распаковки там 6-8Гиг. Не меньше. Теперь это всё надо считать в кучу 1.2Гб, так чтобы оно туда поместилось. Так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:10:47 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
BlazkowiczОзверинДлина строки сильно варьироваться может. Условно мы говорим о 1500 символах в строке. (примерно такой порядок) Насчет кол-ва сущностей, очень трудно сказать. 1 уникальный ключ на строку - может быть >1 уникального ключа на строку - тоже(работаю с логом стороннего разработчика, за что купил, как говорится) <1 уникального ключа на строку - если она будет агрегирована с предыдущими строками Теперь я озадачен, чуть более чем полностью. Имеем 4Гб упакованый файл (zip). Можно предположить что после распаковки там 6-8Гиг. Не меньше. Теперь это всё надо считать в кучу 1.2Гб, так чтобы оно туда поместилось. Так? да, но хранение данных на винте и в памяти - разные вещи. В java достаточно эффективно организовано хранение символьных данных. Я не спорю, что 1200 вполне вероятно, что мало. Но есть подозрение, что может и хватить. Подозрение основано на том, что еще недавно хватало ;) Я пока ищу, что такого я изменил, что перестало...по сути - добавил несколько полей в сущность.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:24:50 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
BlazkowiczТеперь я озадачен, чуть более чем полностью. Имеем 4Гб упакованый файл (zip). Можно предположить что после распаковки там 6-8Гиг. Не меньше. Теперь это всё надо считать в кучу 1.2Гб, так чтобы оно туда поместилось. Так?Не совсем. Если отсортировать распакованный поток, то возможны варианты. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:45:08 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovНе совсем. Если отсортировать распакованный поток, то возможны варианты. У автора одна строка - одна сущность. И сколько сущностей он не знает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:48:20 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
ОзверинПодозрение основано на том, что еще недавно хватало ;) Я пока ищу, что такого я изменил, что перестало...по сути - добавил несколько полей в сущность.... А можно вернуть обратно и посмотреть график расхода кучи в jvisualvm? Может было на пределе? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:49:03 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, правы были, филды сущности String с сылкой на char[] c изначальной строки с offset. Короче все 27 миллионов строк в памяти в итоге висят...где то я косячу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 17:50:10 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
BlazkowiczИ сколько сущностей он не знает.В своё время "за ненахождением готового" клепал на коленке "отчёты по трафику". Читались логи TMeter-а, разбирались в sort-ready вид и конвейер "rexx скрипт1|sort|rexx скрипт2 > результат.tsv" выдавал данные для Excel-я. Сколько будет строк на входе - известно только по порядку величины (сотни тысяч-миллионы - скриптец "информировал" в прогресс-столбце :)), а на выходе их должно было стать не более 50-60 тысяч. Становилось. Гарантированно :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 18:01:03 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Первоначальный итог? задачу создавал в тестовом своем проекте, запускал с ключом -XX:+UseCompressedStrings. Когда код перенес в рабочий, ключ забыл. А он реально помогает ;) Вторичная проблема String[] values = line.parse(); Когда мы делаем нечто вроде entity.setColumn1(values[1]); entity.setColumn2(values[2]); entity.setColumn3(values[3]); map.put(entity); то. column1, column2, column3 ссылаются на 1 и тот же массив символов , но каждый со своим смещением, то есть они держат строку в памяти, не давая GC ее подчистить. А сам объект в мапе. Вывод, при условии, что изначально line очень прилично длины, при setColumn копировать не ссылке, а по значению ;) Должно помочь.буду проверять. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 18:25:48 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
ОзверинBlazkowicz, правы были, филды сущности String с сылкой на char[] c изначальной строки с offset. Короче все 27 миллионов строк в памяти в итоге висят...где то я косячу. оффтоп Blazkowicz обычно всегда как в воду глядит. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 22:57:55 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
P.S. Кстати говоря, можно поглядеть на метод String.intern() - для вычитываемой строки :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 22:59:10 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Однако, ИМХО мапредьюс или СУБД для слива данных решение гораздо лучшее. С помощью СУБД проще. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 23:01:18 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
Не, про интерн() лучше, пожалуй, забыть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2012, 23:23:11 |
|
||
|
Java performance & GC
|
|||
|---|---|---|---|
|
#18+
ОзверинПо сути myEntity - это одна строка. String[] values myEntity.setColumn0(values[0]); myEntity.setColumn1(values[1]); myEntity.setColumn2(values[2]); myEntity.setColumnN(values[N]); Но. Для примера ключ1, поле1=1, поле2=10 ключ1, поле1=2, поле2=10 ключ1, поле1=5, поле2=15 если у строк ключ совпадает, то мы просто в 1ой сущности суммируем поле1 и поле2, т.е. не факт, что каждая новая строка создат и кинет в кэш новую сущностьНаверное самым эффективным будет применение СУБД в том или ином виде. Ваша структура ложится на реляционную модель довольно просто. Таблица для ключей, таблица для полей и таблица значений. Банальный EAV. При работу с СУБД вам даже в памяти не нужно держать мапы сущьностей - ищите по ключу в БД. Если есть, то обновляете, иначе заливаете новую. Если начальство на отрез не хочет полноценную СУБД - примените in-memory БД, которая при нехватке памяти скидывает данные на винт. Тогда даже при увеличении исходных данных в 10-ть! раз система будет работоспособной PS при системе с БД ваш код даже не придется сильно исправлять. поскольку нет мапов, то строки сущностей не хранятся в памяти, а значит и объекты создаваемые в текущем коде будет нормально обрабатываться GC. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.02.2012, 00:43:00 |
|
||
|
|

start [/forum/topic.php?all=1&fid=59&tid=2132555]: |
0ms |
get settings: |
17ms |
get forum list: |
19ms |
check forum access: |
6ms |
check topic access: |
6ms |
track hit: |
48ms |
get topic data: |
15ms |
get forum data: |
4ms |
get page messages: |
62ms |
get tp. blocked users: |
2ms |
| others: | 371ms |
| total: | 550ms |

| 0 / 0 |
