Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2 3      [все]
 Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
Добрый день. К дб гриду (TDBGridEh - компонент EhLib 8.0 build 8.0.023) прикручен датасет. FetchAll := False естественно, т.к записей возвращается много, до 100к. Имеется функционал по выводу данных из грида в эксель(самописный). Для этого нужно знать общее кол-во записей в датасете, которое узнаю с помощью следующей процедуры
procedure GetDataSetRows;
var
  bm: TBookmark;
begin
  with FDataSet do
  begin
    DisableControls;
    bm := GetBookmark;
    First;
    FDataSetRows := 0;
    While not Eof do
    begin
      Inc(FDataSetRows);
      Next;
    end;
    GotoBookmark(bm);
    FreeBookmark(bm);
    EnableControls;
  end;
end;

Проблема возникает в цикле,
While not Eof do
    begin
      Inc(FDataSetRows);
      Next;
    end;
приложение съедает память до 1 гб (когда FDataSetRows инкрементируется до ~40к) и завершает работу с ошибкой "Out of memory". Если записей в датасете немного, то все работает без ошибок.

Подскажите, как можно исправить утечку или посчитать кол-во записей в датасете?
Вариант с возвращением кол-ва записей в запросе с сервера не лучший, т.к процедура по печати отчетов универсальная, а запросов для этих самых отчетов больше тысячи, накладно все их дописывать
20 ноя 17, 10:36    [20968149]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
шК0ДЕР,

Это не утечка, а просто не хватает памяти для такого огромного буффера.
20 ноя 17, 10:42    [20968175]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
шК0ДЕР,

Выход один:
1. Для получения каунта использовать отдельно select count(*) from;
2. В отчет выводить постранично (скажем, по 1000 записей). (что-то типа select first 1000 step 5000)
20 ноя 17, 10:45    [20968197]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
Этого то я и боялся...
20 ноя 17, 10:46    [20968205]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
Хотя подожди... При
шК0ДЕР
FetchAll := False

Такого может и не должно быть. Может действительно утечка в компонентах доступа или еще где?
20 ноя 17, 10:48    [20968217]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
Тоже странным показалось, компоненты проверил, вроде чисто. Смотрел при отладке в диспетчере задач, память утекает именно при переборе записей датасета. В Locate() кстати та же проблема.
Пытался решить вот чем:
DBGrid.DataSource.DataSet := nil;
While not Eof do
begin
   Inc(FDataSetRows);
   Next;
end;
DBGrid.DataSource.DataSet := FDataSet;

DBGrid.DataSource.Enabled := False;
While not Eof do
begin
   Inc(FDataSetRows);
   Next;
end;
DBGrid.DataSource.Enabled := True;

заменяя цикл на
Last;
FDataSetRows := RecNo;

Для эксперемента прописал Refresh в цикле, память, потребляемая приложением сбрасывается до обычной - 8к.
20 ноя 17, 10:57    [20968264]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
шК0ДЕР
заменяя цикл на
Last;
FDataSetRows := RecNo;
Если в твоих компонентах работает RecNo после Last, зачем проктология с циклом тогда.
20 ноя 17, 10:59    [20968276]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
YuRock, код не мой. В любом случае при выполнении метода Last(который так и не выполняется до конца) происходит та же котовасия с памятью. Компонент TOracleDataSet, DOA
20 ноя 17, 11:06    [20968330]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
шК0ДЕР,

Может это компонент и не умеет при отключенном FetchAll буффер определенного размера только помнить.
А с другой стороны, вряд ли такое возможно. Ведь всегда должны быть возможны Prev или First. А как такое сделать на уровне базы? Наверно никак. Unfetch какой-нибудь если и есть где-то, то не везде и не всегда может сработать.
Т.ч. Только переделывать.
20 ноя 17, 11:14    [20968381]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
YuRock, разобрался как кол-во строк подсчитывалось. В компоненте было отключено свойство CountAllRecords и ReсordCount возвращал кол-во видимых записей из грида. При включенному свойстве возвращается общее кол-во записей.
Но проблема осталась. При самой печати данных происходит перебор записей датасета. Отчет недоформировывается
20 ноя 17, 11:28    [20968478]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2091
Это нормальное, обычное поведение. Наборы данных обычно держат все данные в памяти. Вот представьте - что всю выборку из базы всунули в память + обвязка (т.к данные в памяти не в raw же хранить).

автор
Ведь всегда должны быть возможны Prev или First.


Проблема даже не в Prev/First, как раз таки Prev/First сделать не проблема. Проблема в том, что вся выборка может понадобится для отображения в гриде и как тогда по-другому сделать? Кроме как тащить весь набор в память.

While not Eof do
    begin
      Inc(FDataSetRows);
      Next;
    end;


Это тоже самое, что FetchAll, это FetchAll и есть.

автор
Подскажите, как можно исправить утечку или посчитать кол-во записей в датасете?


1. Это не утечка памяти. Это обычная, нормальная работа. Наборы именно так и работают.
2. Если не нужно отображать данные в гриде, то можно взять набор, который не тащит все данные в память, а выбирает только текущую запись. В случае IBX, например, это TIBSQL. В других наборах компонент может быть по-разному: от отдельной компоненты до опций в пределах одной.
3. Намного лучше вместо того, что бы считать количество записей на клиенте посчитать их сервером, отдав ему соответствующий запрос (select count(some_field) as counter from database).
20 ноя 17, 11:32    [20968501]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2091
4. Если же нужно отображать набор в гриде - то либо ограничивать количество записей в наборе, либо переходить на 64х.
20 ноя 17, 11:35    [20968520]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
makhaon, с кол-вом записей уже разобрался. Проблема теперь при печати отчета. Хотя способ аналогичен...
While not DataSet.Eof do
begin
   //печать данных
   Next;
end;
Есть еще какие-либо идеи кроме печати данных по частям?
20 ноя 17, 11:40    [20968551]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2091
шК0ДЕР,

автор
переходить на 64х
20 ноя 17, 11:53    [20968599]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2091
сделать отдельный набор именно для печати, как я говорил:
"можно взять набор, который не тащит все данные в память, а выбирает только текущую запись. В случае IBX, например, это TIBSQL"
20 ноя 17, 11:56    [20968608]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
schi
Member

Откуда: Москва
Сообщений: 2353
шК0ДЕР
makhaon, с кол-вом записей уже разобрался. Проблема теперь при печати отчета. Хотя способ аналогичен...
While not DataSet.Eof do
begin
   //печать данных
   Next;
end;
Есть еще какие-либо идеи кроме печати данных по частям?


Использовать unidirectional dataset, например
20 ноя 17, 12:20    [20968687]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
LSV
Member

Откуда: Киев
Сообщений: 30148
Вообще-то чтобы зачитать весь ДС (кот. зачитан не целиком), достаточно стать в его конец (last), в потом вернуться.
Тогда станет известно кол-во записей. И можно начинать экспорт.
20 ноя 17, 13:01    [20968863]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
schi
Member

Откуда: Москва
Сообщений: 2353
LSV
Вообще-то чтобы зачитать весь ДС (кот. зачитан не целиком), достаточно стать в его конец (last), в потом вернуться.
Тогда станет известно кол-во записей. И можно начинать экспорт.


Попробуй на больших объемах, тебе понравится.
20 ноя 17, 13:04    [20968872]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9916
schi
Использовать unidirectional dataset, например
Или вообще не датасет. Что-то типа TIBSQL
20 ноя 17, 13:31    [20969005]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
DimaBr
Member

Откуда:
Сообщений: 10271
Будь я твоим руководителем, я бы заставил тебя пролистать все 100к строк
20 ноя 17, 13:46    [20969055]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
LSV
Member

Откуда: Киев
Сообщений: 30148
schi
LSV
Вообще-то чтобы зачитать весь ДС (кот. зачитан не целиком), достаточно стать в его конец (last), в потом вернуться.
Тогда станет известно кол-во записей. И можно начинать экспорт.


Попробуй на больших объемах, тебе понравится.
А то я не пробовал... :)
Все равно это придется грузить, чтобы экспортировать. Объем вычислений будет одинаковым.
20 ноя 17, 14:44    [20969272]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
DarkMaster
Member

Откуда: Donetsk,Ukraine
Сообщений: 5628
YuRock

Может это компонент и не умеет при отключенном FetchAll буффер определенного размера только помнить.
А с другой стороны, вряд ли такое возможно. Ведь всегда должны быть возможны Prev или First. А как такое сделать на уровне базы? Наверно никак. Unfetch какой-нибудь если и есть где-то, то не везде и не всегда может сработать.
Т.ч. Только переделывать.


Без привязки к конкретному вопросу вставлю свои 5 копеек - есть такая штука как TIB_Cursor (библиотека IBObjects) - там буфер выделяется ровно на одну запись из БД и сам TIB_Cursor умеет только Next(). Самое то для ТС, если найдутся аналоги.
20 ноя 17, 14:52    [20969313]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 3196
Там в этой базе файлы в блобах хранятся что ли? Как-то многова-то веса (аж гигабайт) для всего 40к строчек.
20 ноя 17, 15:02    [20969349]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
JaDi
Там в этой базе файлы в блобах хранятся что ли? Как-то многова-то веса (аж гигабайт) для всего 40к строчек.
Блобы как раз не тянутся. Может, строки длинные
20 ноя 17, 16:00    [20969610]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
А может и SELECT* убрать можно и поможет.
20 ноя 17, 16:01    [20969615]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
Vladimir779
Member

Откуда:
Сообщений: 63
шК0ДЕР
Добрый день. К дб гриду (TDBGridEh - компонент EhLib 8.0 build 8.0.023) прикручен датасет. FetchAll := False естественно, т.к записей возвращается много, до 100к. Имеется функционал по выводу данных из грида в эксель(самописный).

Возможно, отвечаю не совсем по заданному вопросу
Имеет ли смысл выгрузить все данные в грид DBGridEh1 и потом выгрузить все в Excel средствами от EhLib
следует использовать модуль DBGridEhImpExp
uses
DBGridEhImpExp

и выгружать данные из таблицы в Excel без всякого гемора - всего лишь одной строчкой кода
ExportDBGridEhToXlsx(DBGridEh1, 'Тут нужно указать имя файла Excel',[]);

у меня по крайней мере работает и на бОльших данных
использую следующую связку: "Embarcadero® Delphi 10 Seattle Version 23.0.20618.2753" + "компонент EhLib 8.0 build 8.0.021"
20 ноя 17, 16:39    [20969767]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
makhaon
как раз таки Prev/First сделать не проблема
Интересно, как, не храня буффер предыдущей записи на клиенте, когда на сервере её уже нет.
20 ноя 17, 16:50    [20969823]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
Vladimir779, на рабочей форме пользователя такое кол-во позиций явно будет лишним. Придется в момент печати выводить в грид все позиции, а после печати обратно скрыть лишнюю тонну данных. Завтра обязательно попробую. Интересно на сколько быстро будет весь объем в грид выгружаться, т.к событие OnDrawDataCell обрабатывается. Код небольшой, но все же...
20 ноя 17, 17:05    [20969868]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
Vladimir779
шК0ДЕР
Добрый день. К дб гриду (TDBGridEh - компонент EhLib 8.0 build 8.0.023) прикручен датасет. FetchAll := False естественно, т.к записей возвращается много, до 100к. Имеется функционал по выводу данных из грида в эксель(самописный).

Возможно, отвечаю не совсем по заданному вопросу
Имеет ли смысл выгрузить все данные в грид DBGridEh1 и потом выгрузить все в Excel средствами от EhLib
следует использовать модуль DBGridEhImpExp
uses
DBGridEhImpExp

и выгружать данные из таблицы в Excel без всякого гемора - всего лишь одной строчкой кода
ExportDBGridEhToXlsx(DBGridEh1, 'Тут нужно указать имя файла Excel',[]);

у меня по крайней мере работает и на бОльших данных
использую следующую связку: "Embarcadero® Delphi 10 Seattle Version 23.0.20618.2753" + "компонент EhLib 8.0 build 8.0.021"

Совсем обалдели. В грид-то - зачем грузить?
20 ноя 17, 17:08    [20969883]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
шК0ДЕР
...Имеется функционал по выводу данных из грида в эксель(самописный). Для этого нужно знать общее кол-во записей в датасете...

Расскажи, пожалуйста - для чего тебе при выводе в эксель знать общее количество записей в датасете?
20 ноя 17, 17:25    [20969926]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
Vladimir779
Member

Откуда:
Сообщений: 63
чччД,

для того что бы содержимое грида выгрузить в Эксель
20 ноя 17, 17:45    [20969969]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
Vladimir779
Member

Откуда:
Сообщений: 63
шК0ДЕР
Vladimir779, на рабочей форме пользователя такое кол-во позиций явно будет лишним. Придется в момент печати выводить в грид все позиции, а после печати обратно скрыть лишнюю тонну данных. Завтра обязательно попробую. Интересно на сколько быстро будет весь объем в грид выгружаться, т.к событие OnDrawDataCell обрабатывается. Код небольшой, но все же...


Попробуй вариант со скрытым гридом от глаз пользователя, грид для выгрузки данных в Эксель, в этом гриде можешь не использовать событие OnDrawDataCell
20 ноя 17, 17:48    [20969993]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9916
чччД
знать общее количество записей в датасете?
Vladimir779
что бы содержимое грида выгрузить в Эксель
не вижу взимосвязи
20 ноя 17, 18:09    [20970035]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
Vladimir779
шК0ДЕР
Vladimir779, на рабочей форме пользователя такое кол-во позиций явно будет лишним. Придется в момент печати выводить в грид все позиции, а после печати обратно скрыть лишнюю тонну данных. Завтра обязательно попробую. Интересно на сколько быстро будет весь объем в грид выгружаться, т.к событие OnDrawDataCell обрабатывается. Код небольшой, но все же...


Попробуй вариант со скрытым гридом от глаз пользователя, грид для выгрузки данных в Эксель, в этом гриде можешь не использовать событие OnDrawDataCell


Это троллинг такой, что ли?
Или просто альтернативно одаренные общаются?
20 ноя 17, 18:43    [20970091]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
DarkMaster
Member

Откуда: Donetsk,Ukraine
Сообщений: 5628
чччД
Попробуй вариант со скрытым гридом от глаз пользователя, грид для выгрузки данных в Эксель, в этом гриде можешь не использовать событие OnDrawDataCell


Это троллинг такой, что ли?
Или просто альтернативно одаренные общаются?[/quot]

Ну как это зачем? Чтобы побольше граблей в темной комнате раскидать, а потом героически с ними бороться.
20 ноя 17, 18:56    [20970120]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
DarkMaster
Member

Откуда: Donetsk,Ukraine
Сообщений: 5628
чччД,

Что-то цитирование съехало напрочь :(
20 ноя 17, 18:56    [20970122]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
DarkMaster
Ну как это зачем? Чтобы побольше граблей в темной комнате раскидать

Не только, а чтобы еще в 2 раза более правильным казалось, для самоутверждения, решение перейти на 64 бита.
20 ноя 17, 18:58    [20970128]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
Vladimir779
Member

Откуда:
Сообщений: 63
_Vasilisk_
чччД
знать общее количество записей в датасете?
Vladimir779
что бы содержимое грида выгрузить в Эксель
не вижу взимосвязи

я изначально указал "Возможно, отвечаю не совсем по заданному вопросу"
именно поэтому не видно никакой взаиомосвязи
20 ноя 17, 19:30    [20970172]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
Vladimir779
Member

Откуда:
Сообщений: 63
DarkMaster
чччД
Попробуй вариант со скрытым гридом от глаз пользователя, грид для выгрузки данных в Эксель, в этом гриде можешь не использовать событие OnDrawDataCell

Это троллинг такой, что ли?
Или просто альтернативно одаренные общаются?

Ну как это зачем? Чтобы побольше граблей в темной комнате раскидать, а потом героически с ними бороться.[/quot]
Критиковать все могут, а можешь предложить рабочий вариант, и что бы без граблей ?
20 ноя 17, 19:31    [20970176]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
Vladimir779
Member

Откуда:
Сообщений: 63
DarkMaster
Ну как это зачем? Чтобы побольше граблей в темной комнате раскидать, а потом героически с ними бороться.

Критиковать все могут, а можешь предложить рабочий вариант, и что бы без граблей ?
20 ноя 17, 19:32    [20970180]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
Vladimir779
DarkMaster
Ну как это зачем? Чтобы побольше граблей в темной комнате раскидать, а потом героически с ними бороться.

Критиковать все могут, а можешь предложить рабочий вариант, и что бы без граблей ?

Ну, напрягись чуть-чуть.
Подсказки:
1. Задумайся по поводу: "а для чего грузить весь датасет в память, если экспорт в MS Excel все равно выполняется построчно?"
2. И тем более - для чего к этоve несчастному датасету подключать TDBGridEh, если ты вообще не собираешься этот грид показывать.
3. Посмотри на реализацию класса TDBGridEhExportAsXLS - там комментария больше, чем кода. А полезного кода - пара десятков строк всего.
20 ноя 17, 20:02    [20970222]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2091
Vladimir779,

Так я же уже всё расписал :) Если отображать в гриде не нужно, то незачем тащить набор в память. Если нужно, то нужно либо 64х, либо ограничивать размер выборки. Считать количество компонентой тоже не нужно, а запросом. Даже запрос написал :)

makhaon
как раз таки Prev/First сделать не проблема

YuRock
Интересно, как, не храня буффер предыдущей записи на клиенте, когда на сервере её уже нет.


Да, точно, набор однонаправленный же. Неверно написал.
20 ноя 17, 22:51    [20970545]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
DimaBr
Member

Откуда:
Сообщений: 10271
Ой сомневаюсь что пользователю понравится файл с 100к строк.

Посадить бы дарование, чтобы написал формулу в полученном Экселе для умножения суммы 1,3,5,7,9 стоки на разнность в 2,4,6,8,10, в каждом чётном десятке. По всем 100к строчкам.
20 ноя 17, 22:55    [20970553]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
DimaBr
Ой сомневаюсь что пользователю понравится файл с 100к строк.

Посадить бы дарование, чтобы написал формулу в полученном Экселе для умножения суммы 1,3,5,7,9 стоки на разнность в 2,4,6,8,10, в каждом чётном десятке. По всем 100к строчкам.

Мы недавно задание специальное выполняли, по реализации отчета несуразных размеров и структуры. Уж что там заказчик собирается с ним делать - не наша забота.
Возможно, он его (за неделю, не быстрее) распечатает, украсит подписями и печатями, погрузит на грузовики и отвезет в глубокий подземный бункер.
20 ноя 17, 23:03    [20970563]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
DimaBr
Ой сомневаюсь что пользователю понравится файл с 100к строк.
Был у меня случай, когда клиент возмутился тем, что в отчет в экселе попадают только первые 65535 строк. Вот тогда и пришлось на xlsx переходить)
20 ноя 17, 23:57    [20970654]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
DimaBr
Member

Откуда:
Сообщений: 10271
А некоторые по миллиону в Лукап пихают
21 ноя 17, 01:26    [20970721]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
Dunkin
Guest
makhaon
Если нужно, то нужно либо 64х, либо ограничивать размер выборки. Считать количество компонентой тоже не нужно, а запросом. Даже запрос написал :)

64 бита не решат проблему времени при загрузке данных в датасет. Компонент тоже специфический и как раз выполняет select count(*) в CountAllRecords.

Как уже написали, грузить всё не нужно.
У TOracleDataSet есть свойство UniDirectional. Но лучше использовать TOracleQuery.
21 ноя 17, 02:54    [20970746]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
Vladimir779
Member

Откуда:
Сообщений: 63
чччД
Ну, напрягись чуть-чуть.
Подсказки:
1. Задумайся по поводу: "а для чего грузить весь датасет в память, если экспорт в MS Excel все равно выполняется построчно?"
2. И тем более - для чего к этоve несчастному датасету подключать TDBGridEh, если ты вообще не собираешься этот грид показывать.
3. Посмотри на реализацию класса TDBGridEhExportAsXLS - там комментария больше, чем кода. А полезного кода - пара десятков строк всего.

Возможно, я чего-то недопонимаю, благодарю за наводку, в свободное время рассмотрю каждый пункт
21 ноя 17, 07:09    [20970819]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
DimaBr
Ой сомневаюсь что пользователю понравится файл с 100к строк.

Это справочники товара и прайс листы, пользователям(финансистам, маркетологам) именно НУЖНО, в противном случае и тему не завел бы.
DimaBr
Посадить бы дарование, чтобы написал формулу в полученном Экселе для умножения суммы 1,3,5,7,9 стоки на разнность в 2,4,6,8,10, в каждом чётном десятке. По всем 100к строчкам.

Никакие вычисления там не требуются, а если бы и требовались, то производились исключительно на сервере...
21 ноя 17, 08:11    [20970854]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
Vladimir779
чччД
Ну, напрягись чуть-чуть.
Подсказки:
1. Задумайся по поводу: "а для чего грузить весь датасет в память, если экспорт в MS Excel все равно выполняется построчно?"
2. И тем более - для чего к этоve несчастному датасету подключать TDBGridEh, если ты вообще не собираешься этот грид показывать.
3. Посмотри на реализацию класса TDBGridEhExportAsXLS - там комментария больше, чем кода. А полезного кода - пара десятков строк всего.

Возможно, я чего-то недопонимаю, благодарю за наводку, в свободное время рассмотрю каждый пункт

Ну да, думать некогда... трясти надо...
21 ноя 17, 09:17    [20971016]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
Vladimir779
шК0ДЕР
Добрый день. К дб гриду (TDBGridEh - компонент EhLib 8.0 build 8.0.023) прикручен датасет. FetchAll := False естественно, т.к записей возвращается много, до 100к. Имеется функционал по выводу данных из грида в эксель(самописный).

Возможно, отвечаю не совсем по заданному вопросу
Имеет ли смысл выгрузить все данные в грид DBGridEh1 и потом выгрузить все в Excel средствами от EhLib
следует использовать модуль DBGridEhImpExp
uses
DBGridEhImpExp

и выгружать данные из таблицы в Excel без всякого гемора - всего лишь одной строчкой кода
ExportDBGridEhToXlsx(DBGridEh1, 'Тут нужно указать имя файла Excel',[]);

у меня по крайней мере работает и на бОльших данных
использую следующую связку: "Embarcadero® Delphi 10 Seattle Version 23.0.20618.2753" + "компонент EhLib 8.0 build 8.0.021"


Сработало, даже без выгрузки всех данных в грид, очень быстро.
Спасибо всем за советы!
21 ноя 17, 09:18    [20971017]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
шК0ДЕР
Vladimir779
пропущено...

Возможно, отвечаю не совсем по заданному вопросу
Имеет ли смысл выгрузить все данные в грид DBGridEh1 и потом выгрузить все в Excel средствами от EhLib
следует использовать модуль DBGridEhImpExp
uses
DBGridEhImpExp

и выгружать данные из таблицы в Excel без всякого гемора - всего лишь одной строчкой кода
ExportDBGridEhToXlsx(DBGridEh1, 'Тут нужно указать имя файла Excel',[]);

у меня по крайней мере работает и на бОльших данных
использую следующую связку: "Embarcadero® Delphi 10 Seattle Version 23.0.20618.2753" + "компонент EhLib 8.0 build 8.0.021"


Сработало, даже без выгрузки всех данных в грид, очень быстро.
Спасибо всем за советы!

п....ц приплыли.
21 ноя 17, 09:21    [20971022]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
шК0ДЕР
Сработало
Функцию эту не смотрел, но она не может не использовать тот же цикл перебора датасета, что и у тебя. А значит, сработало потому, что ты что-то изменил. Список полей в select'е, например.
21 ноя 17, 11:47    [20971604]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
YuRock, и это тоже. Половину неиспользуемых исключил
21 ноя 17, 11:51    [20971631]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 2468
шК0ДЕР
Половину неиспользуемых исключил

Именно это помогло.
21 ноя 17, 14:20    [20972221]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2091
потом записей станет больше и всё вернётся на круги. и так будет, пока нормально не сделаешь.
22 ноя 17, 16:02    [20975575]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
В общем решил проблему используя TOracleQuery, которому не нужно хранить в памяти весь набор данных. Отказался от стандартной выгрузки из грида с помощью функции ExportDBGridEhToXlsx, т.к она лажевая (Но быстрая). Никакого форматирования, при наличии большого кол-ва полей все сливается.

Проекту 15 лет, для выгрузки данных в эксель используется самописный компонент(мощная универсальная штука), в котором как раз и производится подсчет общего кол-ва строк(для последующего выделения диапазона ячеек и вставки в него данных), затем все данные заносятся в многомерный массив(видимо разрабы не рассчитывали на большое кол-во данных). Получение кол-ва строк поправил, манипулируя свойствами DataSet`a, а вот при занесении данных в массив происходит та же лажа - Out of memory.

Временно сделал корявую обработку, т.к. пользователи беснуются:
try
   //занесение данных в массив
except
  on E:Exception do
     if Pos('out of memory', LowerCase(E.Message)) > 0  then
     //Вызов процедуры, в которой данные возвращаются с помощью TOracleQuery с последующей печатью(без массивов) 
end;

Буду думать, как переписать компонент заменив DataSet на OracleQuery
6 дек 17, 13:44    [21010783]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
шК0ДЕР
в котором как раз и производится подсчет общего кол-ва строк
...
как переписать компонент заменив DataSet на OracleQuery
- заюзать select count() - не, никак?
6 дек 17, 13:52    [21010833]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
schi
Member

Откуда: Москва
Сообщений: 2353
шК0ДЕР
Буду думать, как переписать компонент заменив DataSet на OracleQuery


Сделать обертку (декоратор) и использовать ее внутри компонента.
6 дек 17, 13:54    [21010850]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
Если прочитать дальше, то найдете это
шК0ДЕР
Получение кол-ва строк поправил, манипулируя свойствами DataSet`a
6 дек 17, 13:55    [21010857]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
шК0ДЕР
Если прочитать дальше, то найдете это
шК0ДЕР
Получение кол-ва строк поправил, манипулируя свойствами DataSet`a

Поделись же, чем ты манипулировал.
6 дек 17, 13:59    [21010882]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
чччД,

20968478
6 дек 17, 14:08    [21010942]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
шК0ДЕР
чччД,

20968478

шК0ДЕР
YuRock, разобрался как кол-во строк подсчитывалось. В компоненте было отключено свойство CountAllRecords и ReсordCount возвращал кол-во видимых записей из грида. При включенному свойстве возвращается общее кол-во записей.
Но проблема осталась. При самой печати данных происходит перебор записей датасета. Отчет недоформировывается


А ты смотрел в исходниках, как высчитывается ReсordCount при включенном CountAllRecords? Загрузкой всего датасета или отдельным запросом к серверу?
6 дек 17, 14:13    [21010973]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
чччД,

не смотрел, но работает очень даже шустро, не похоже, чтобы весь датасет грузил
6 дек 17, 14:23    [21011030]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
defecator
Member

Откуда:
Сообщений: 35434
чччД
шК0ДЕР
чччД,

20968478

шК0ДЕР
YuRock, разобрался как кол-во строк подсчитывалось. В компоненте было отключено свойство CountAllRecords и ReсordCount возвращал кол-во видимых записей из грида. При включенному свойстве возвращается общее кол-во записей.
Но проблема осталась. При самой печати данных происходит перебор записей датасета. Отчет недоформировывается


А ты смотрел в исходниках, как высчитывается ReсordCount при включенном CountAllRecords? Загрузкой всего датасета или отдельным запросом к серверу?

в DOA делается отдельный запрос
Select count(1) from (текст основного запроса)
6 дек 17, 14:25    [21011039]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
чччД
Guest
defecator,
понял, спасибо.
6 дек 17, 14:26    [21011048]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
schi
шК0ДЕР
Буду думать, как переписать компонент заменив DataSet на OracleQuery


Сделать обертку (декоратор) и использовать ее внутри компонента.


А можно поподробней?
Гугл подсказал: "Язык Delphi поддерживает class helpers, которые делают ненужным использование шаблона декоратор"
6 дек 17, 14:30    [21011078]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
schi
Member

Откуда: Москва
Сообщений: 2353
шК0ДЕР,

Как-то так:

type
  IDataSetDecorator = interface
    ['{3D9E4FE7-837C-4004-9822-30A604EF424B}']
    function FieldByName(const AName: WideString): TField;
    function GetFields: TFields;
    function GetRecordCount: Integer;
    function GetName: string;
    function ExecSQLAndFetch: Boolean;
    function Fetch: Boolean;
    property Fields: TFields read GetFields;
    property RecordCount: Integer read GetRecordCount;
    property Name: string read GetName;
  end;


Сама выгрузка в Excel работает с методами этого интерфейса, а среди реализаций есть как с двунаправленным DataSet, так и с однонаправленным самописным доступом к Oracle
6 дек 17, 21:01    [21012744]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти при работе с DataSet  [new]
шК0ДЕР
Member

Откуда: Сызрань, городок на Волге
Сообщений: 71
schi, спасибо
7 дек 17, 08:26    [21013465]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2 3      [все]
Все форумы / Delphi Ответить