|
|
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
Добрый день. К дб гриду (TDBGridEh - компонент EhLib 8.0 build 8.0.023) прикручен датасет. FetchAll := False естественно, т.к записей возвращается много, до 100к. Имеется функционал по выводу данных из грида в эксель(самописный). Для этого нужно знать общее кол-во записей в датасете, которое узнаю с помощью следующей процедуры Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Проблема возникает в цикле, Код: pascal 1. 2. 3. 4. 5. приложение съедает память до 1 гб (когда FDataSetRows инкрементируется до ~40к) и завершает работу с ошибкой "Out of memory". Если записей в датасете немного, то все работает без ошибок. Подскажите, как можно исправить утечку или посчитать кол-во записей в датасете? Вариант с возвращением кол-ва записей в запросе с сервера не лучший, т.к процедура по печати отчетов универсальная, а запросов для этих самых отчетов больше тысячи, накладно все их дописывать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 10:36 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
шК0ДЕР, Это не утечка, а просто не хватает памяти для такого огромного буффера. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 10:42 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
шК0ДЕР, Выход один: 1. Для получения каунта использовать отдельно select count(*) from; 2. В отчет выводить постранично (скажем, по 1000 записей). (что-то типа select first 1000 step 5000) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 10:45 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
Этого то я и боялся... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 10:46 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
Хотя подожди... При шК0ДЕРFetchAll := False Такого может и не должно быть. Может действительно утечка в компонентах доступа или еще где? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 10:48 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
Тоже странным показалось, компоненты проверил, вроде чисто. Смотрел при отладке в диспетчере задач, память утекает именно при переборе записей датасета. В Locate() кстати та же проблема. Пытался решить вот чем: Код: pascal 1. 2. 3. 4. 5. 6. 7. Код: pascal 1. 2. 3. 4. 5. 6. 7. заменяя цикл на Код: pascal 1. 2. Для эксперемента прописал Refresh в цикле, память, потребляемая приложением сбрасывается до обычной - 8к. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 10:57 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
шК0ДЕРзаменяя цикл на Код: pascal 1. 2. Если в твоих компонентах работает RecNo после Last, зачем проктология с циклом тогда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 10:59 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
YuRock, код не мой. В любом случае при выполнении метода Last(который так и не выполняется до конца) происходит та же котовасия с памятью. Компонент TOracleDataSet, DOA ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 11:06 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
шК0ДЕР, Может это компонент и не умеет при отключенном FetchAll буффер определенного размера только помнить. А с другой стороны, вряд ли такое возможно. Ведь всегда должны быть возможны Prev или First. А как такое сделать на уровне базы? Наверно никак. Unfetch какой-нибудь если и есть где-то, то не везде и не всегда может сработать. Т.ч. Только переделывать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 11:14 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
YuRock, разобрался как кол-во строк подсчитывалось. В компоненте было отключено свойство CountAllRecords и ReсordCount возвращал кол-во видимых записей из грида. При включенному свойстве возвращается общее кол-во записей. Но проблема осталась. При самой печати данных происходит перебор записей датасета. Отчет недоформировывается ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 11:28 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
Это нормальное, обычное поведение. Наборы данных обычно держат все данные в памяти. Вот представьте - что всю выборку из базы всунули в память + обвязка (т.к данные в памяти не в raw же хранить). авторВедь всегда должны быть возможны Prev или First. Проблема даже не в Prev/First, как раз таки Prev/First сделать не проблема. Проблема в том, что вся выборка может понадобится для отображения в гриде и как тогда по-другому сделать? Кроме как тащить весь набор в память. Код: pascal 1. 2. 3. 4. 5. Это тоже самое, что FetchAll, это FetchAll и есть. авторПодскажите, как можно исправить утечку или посчитать кол-во записей в датасете? 1. Это не утечка памяти. Это обычная, нормальная работа. Наборы именно так и работают. 2. Если не нужно отображать данные в гриде, то можно взять набор, который не тащит все данные в память, а выбирает только текущую запись. В случае IBX, например, это TIBSQL. В других наборах компонент может быть по-разному: от отдельной компоненты до опций в пределах одной. 3. Намного лучше вместо того, что бы считать количество записей на клиенте посчитать их сервером, отдав ему соответствующий запрос (select count(some_field) as counter from database). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 11:32 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
4. Если же нужно отображать набор в гриде - то либо ограничивать количество записей в наборе, либо переходить на 64х. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 11:35 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
makhaon, с кол-вом записей уже разобрался. Проблема теперь при печати отчета. Хотя способ аналогичен... Код: pascal 1. 2. 3. 4. 5. Есть еще какие-либо идеи кроме печати данных по частям? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 11:40 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
шК0ДЕР, авторпереходить на 64х ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 11:53 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
сделать отдельный набор именно для печати, как я говорил: "можно взять набор, который не тащит все данные в память, а выбирает только текущую запись. В случае IBX, например, это TIBSQL" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 11:56 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
шК0ДЕРmakhaon, с кол-вом записей уже разобрался. Проблема теперь при печати отчета. Хотя способ аналогичен... Код: pascal 1. 2. 3. 4. 5. Есть еще какие-либо идеи кроме печати данных по частям? Использовать unidirectional dataset, например ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 12:20 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
Вообще-то чтобы зачитать весь ДС (кот. зачитан не целиком), достаточно стать в его конец (last), в потом вернуться. Тогда станет известно кол-во записей. И можно начинать экспорт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 13:01 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
LSVВообще-то чтобы зачитать весь ДС (кот. зачитан не целиком), достаточно стать в его конец (last), в потом вернуться. Тогда станет известно кол-во записей. И можно начинать экспорт. Попробуй на больших объемах, тебе понравится. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 13:04 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
schiИспользовать unidirectional dataset, напримерИли вообще не датасет. Что-то типа TIBSQL ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 13:31 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
Будь я твоим руководителем, я бы заставил тебя пролистать все 100к строк ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 13:46 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
schiLSVВообще-то чтобы зачитать весь ДС (кот. зачитан не целиком), достаточно стать в его конец (last), в потом вернуться. Тогда станет известно кол-во записей. И можно начинать экспорт. Попробуй на больших объемах, тебе понравится.А то я не пробовал... :) Все равно это придется грузить, чтобы экспортировать. Объем вычислений будет одинаковым. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 14:44 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
YuRock Может это компонент и не умеет при отключенном FetchAll буффер определенного размера только помнить. А с другой стороны, вряд ли такое возможно. Ведь всегда должны быть возможны Prev или First. А как такое сделать на уровне базы? Наверно никак. Unfetch какой-нибудь если и есть где-то, то не везде и не всегда может сработать. Т.ч. Только переделывать. Без привязки к конкретному вопросу вставлю свои 5 копеек - есть такая штука как TIB_Cursor (библиотека IBObjects) - там буфер выделяется ровно на одну запись из БД и сам TIB_Cursor умеет только Next(). Самое то для ТС, если найдутся аналоги. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 14:52 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
Там в этой базе файлы в блобах хранятся что ли? Как-то многова-то веса (аж гигабайт) для всего 40к строчек. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 15:02 |
|
||
|
Утечка памяти при работе с DataSet
|
|||
|---|---|---|---|
|
#18+
JaDiТам в этой базе файлы в блобах хранятся что ли? Как-то многова-то веса (аж гигабайт) для всего 40к строчек.Блобы как раз не тянутся. Может, строки длинные ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2017, 16:00 |
|
||
|
|

start [/forum/topic.php?fid=58&startmsg=39555982&tid=2041465]: |
0ms |
get settings: |
7ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
199ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
| others: | 230ms |
| total: | 533ms |

| 0 / 0 |
