Форум » GUI » Неисправимая ошибка 9009 или 9006 » Ответить

Неисправимая ошибка 9009 или 9006

Andrey: Прога на большой базе - 71 тыс.записей вылетает вот с такой ошибкой в error.log: [pre2]Info: Harbour MiniGUI Extended Edition 20.12.0 (32-bit) Неисправимая ошибка 9009: hb_xrealloc ене может перераспределить память Called from DBAPPEND(0) Called from CREATEMEMTMP(1310) in Demo2.prg Called from MAIN(109) in Demo2.prg ------------------------------------------------------------------------[/pre2] Вот выборочный код: [pre2]REQUEST HB_MEMIO ... DBCREATE( cFileTmp, aStru, cVia, .T., cAlsTmp ) // область cAlsTmp k := FieldPos( cFld ) FOR i := 1 TO (cAlias)->( LastRec() ) SELECT(cAlsTmp) APPEND BLANK // строка 1310 FieldPut( k, i ) SELECT(cAlias) DBGOTO(i) IF (cAlias)->( DELETED() ) (cAlsTmp)->( DbDelete() ) ENDIF DO EVENTS NEXT[/pre2] Из одной базы копирую записи в новую базу MEMIO Как с этим бороться / что править ? [img class=smile" src=/gif/smk/sm33.gif] PS. База создаётся объемом 415 Мб ( пробовал писать на диск) два раза, прога ломается на создании второй базы. Просто этот пример - продолжение Tsb_VirtualColumn и в этой проге 2 раза создаётся временная база.

Ответов - 26, стр: 1 2 All

Andrey: Если делаю копирование в обычную (временную) базу, то прога вылетает вот по такой ошибке: [pre2]Error MGERROR/0 Only Panel windows can be defined inside a DEFINE WINDOW...END WINDOW structure. Program terminated. --------------------------------- Stack Trace --------------------------------- Called from MSGMINIGUIERROR(100) in module: h_error.prg Called from _DEFINEWINDOW(150) in module: h_windows.prg Called from WAITWINDOW(2776) in module: h_windows.prg Called from MYCOLORSINITTEMPDBF(684) in module: Demo2.prg Called from MYBRW(302) in module: Demo2.prg Called from MAIN(174) in module: Demo2.prg [/pre2] По коду совсем непонятно, строка 684 в MYCOLORSINITTEMPDBF(684) вот такая: [pre2] WaitWindow( "Wait, color is being written to dbf file", .T. ) [/pre2] PS. База создаётся объемом 415 Мб, но на показе прога ломается. Как исправить эту ошибку ?

PSP: Andrey пишет: Неисправимая ошибка 9009: hb_xrealloc ене может перераспределить память .... Из одной базы копирую записи в новую базу MEMIO Просто кончается память.

Andrey: PSP пишет: Просто кончается память. Как можно определить размер доступной памяти для МиниГуи, чтобы уже при старте программы определить какую базу можно создавать ? Т.е. база MEMIO или база на диске ?


Pasha: Не надо ничего определять. Хранить таблицу в памяти, которая потенциально может занимать сотни мегабайт не есть хорошее решение. Причем этот блок памяти для таблицы должен быть одним фрагментом. Пусть мы имеем таблицу в памяти, и размер блока, в котором она находится, исчерпался Выдаем dbAppend(), надо перевыделить память. Вызывается xrealloc. Для его отработки надо найти блок памяти больше текущего, и переписать в него содержимое таблицы, и освободить занимаемый блок. Т.е необходимо иметь свободным двойной размер таблицы, что совсем нехорошо Память когда-нибудь да исчерпается Определять свободную память при старте бессмысленно. В любой момент стартанет какой-нибудь браузер, и скушает сотни мегабайт. И не только браузер

SergKis: Andrey пишет Only Panel windows can be defined inside a DEFINE WINDOW...END WINDOW structure. Program terminated Сообщение говорит о том, что ты не завершив создание окна по END WINDOW начинаешь создавать др. окно и оно не Panel.

Andrey: SergKis пишет: Сообщение говорит о том, что ты не завершив создание окна по END WINDOW начинаешь создавать др. окно и оно не Panel. Спасибо ! Понял что при малых ДБФ это не важно, главное окно успевает про рисоваться, а если БД большие, то не успевает.

Andrey: Мучаю пример MiniGUI\SAMPLES\Advanced\Tsb_VirtualColumn\demo1.prg Поставил базу 266 Mb, 930 полей - пример вылетает с ошибкой: [pre2]Info: Harbour MiniGUI Extended Edition 20.12.0 (32-bit) Неисправимая ошибка 9006: hb_xgrab не может распределить память Called from ARRAY(0) Called from MYCOLUMNINIT(404) in Demo1.prg Called from MYBRW2(263) in Demo1.prg Called from MAIN(142) in Demo1.prg[/pre2] Вылетает на втором этапе при создании массива размером 71000х930 Поставил поменьше базу demoAb.dbf ( 133 Mb, 930 полей) - пример работает ! Массив размером 35000х930 А можно как то отловить нехватку памяти при создании массива и выдать ошибку ?

alkresin: Попробуйте Memory( n ) для проверки доступной памяти. Вот возможные параметры: [pre2] #define HB_MEM_CHAR 0 /* Free Variable Space (KB) */ #define HB_MEM_BLOCK 1 /* Largest String (KB) */ #define HB_MEM_RUN 2 /* RUN Memory (KB) */ /* CA-Cl*pper undocumented */ #define HB_MEM_VM 3 /* Virtual Memory (KB) */ #define HB_MEM_EMS 4 /* Free Expanded Memory (KB) (?) */ #define HB_MEM_FM 101 /* Fixed Memory/Heap (KB) (?) */ #define HB_MEM_FMSEGS 102 /* Segments in Fixed Memory/Heap (?) */ #define HB_MEM_SWAP 103 /* Free Swap Memory (KB) */ #define HB_MEM_CONV 104 /* Free Conventional (KB) */ #define HB_MEM_EMSUSED 105 /* Used Expanded Memory (KB) (?) */ /* Harbour extensions */ #define HB_MEM_USED 1001 /* Memory used (bytes) */ #define HB_MEM_USEDMAX 1002 /* Maximum memory used (bytes) */ #define HB_MEM_STACKITEMS 1003 /* Total items on the stack */ #define HB_MEM_STACK 1004 /* Total memory size used by the stack (bytes) */ #define HB_MEM_STACK_TOP 1005 /* Total items currently on the stack */ #define HB_MEM_BLOCKS 1007 /* Total number of memory blocks allocated */ #define HB_MEM_STATISTICS 1008 /* Return non 0 value if FM statistic is enabled */ #define HB_MEM_CANLIMIT 1009 /* Return non 0 value if used memory limit is supported */ [/pre2] Может, какие-нибудь подойдут для оценки.

alkresin: И не забывайте "сборку мусора" делать во время длительных процессов (hb_gcAll(), hb_gcStep()), это иногда спасает от переполнения памяти.

SergKis: Andrey пишет Вылетает на втором этапе при создании массива размером 71000х930 Поставил поменьше базу demoAb.dbf ( 133 Mb, 930 полей) - пример работает ! Массив размером 35000х930 На мой взгляд, это лишено смысла давать таблицу в просмотр из 71000 и 35000 записей. 1000 записей на экране трудно отследить, а тут ... Выборки надо делать, разрезы, как по строкам, так и по колонкам. Просто делать scroll влево\вправо на 930 колонок офигеешь, что то найти глазами. А сборку мусора можно вставлять перед созданием окон.

SergKis: PS Или не пытаться забивать все в память, а работать через диск

Pasha: Вылетает на втором этапе при создании массива размером 71000х930 Поставил поменьше базу demoAb.dbf ( 133 Mb, 930 полей) - пример работает ! Массив размером 35000х930 А можно как то отловить нехватку памяти при создании массива и выдать ошибку ? Это же опять сотни мегабайт, если не гигабайты. Хоть и не одним фрагментом. Не надо отлавливать количество памяти. Любой инструмент надо использовать по назначению, если не хочется его сломать

Pasha: Для понимания: размер элемента HB_ITEM в 32-битной системе - 24 байта. Для хранения массива 71000х930 необходимо 66030000 таких элементов, каждый по 24 байта, всего получается более 1.5Г. Это не считая самих данных, плюс служебная информация на каждый блок памяти Всего получится несколько гигабайт. А зачем ?

Andrey: SergKis пишет: Выборки надо делать, разрезы, как по строкам, так и по колонкам. Просто делать scroll влево\вправо на 930 колонок офигеешь, что то найти глазами. Согласен с этим полностью. Но у нас же в примере есть справа виртуальные колонки и фильтр по колонке. Вот фильтр включаешь и смотришь. Хотя листать 930 колонок то ещё удовольствие. Наверное нужно делать отдельный показ по нужным колонкам, не нужны же сразу все колонки. Как правило нужны несколько колонок и всё. Pasha пишет: Всего получится несколько гигабайт. А зачем ? Делал просто пример под задачу сравнения двух dbf и показ отличий в ТСБ. Думал сделать показ различия строк и колонок цветами, а цвета загнать в массив или во временную базу. Для небольших баз идеология примера работает на отлично ! Но вот поставил реальные базы, вот тут случился облом. Я понял, что был неправ со своим подходом. Но без этих примеров трудно было бы понять, что подход не верен. Зато теперь знаю ! Pasha пишет: Любой инструмент надо использовать по назначению, если не хочется его сломать Заранее не подумал, что не так делаю и какой результат будет на больших базах.

SergKis: Andrey пишет Для небольших баз идеология примера работает на отлично ! Но вот поставил реальные базы, вот тут случился облом. Я понял, что был неправ со своим подходом. Но без этих примеров трудно было бы понять, что подход не верен. Подход нормальный, если, к примеру, работать по 100 строк, т.е. сравниваешь 100 записей одного dbf со 100 записями другого и если надо добавляешь еще строки в список или очищаешь его и снова добавляешь по 100 строк. Т.е. в списках можешь накапливать обозреваемое ко-во строк (до 500 или 1000) и всегда работать в выборкой, а не полным файлом. А по горизонтали колонки группировать и просматривать выбранную группу

SergKis: PS Можно вместо группирования колонок использовать маркеры на колонки, прыгать по ним и далее по стрелам ->, <-

SergKis: SergKis пишет Подход нормальный, если, к примеру, работать по 100 строк, т.е. сравниваешь 100 записей одного dbf со 100 записями другого Уточнение. Сравнение производим для всего файла, а вот в просмотр берем по 100 строк (цифры итоги в тсб в Footer показываем правильно)

Andrey: Понял тебя ! Учту это в следующем примере. Добиваю этот пример - Demo2.prg. На реальной базе опять ломается в другом месте: [pre2]Неисправимая ошибка 9006: hb_xgrab не может распределить память Called from ARRAY(0) Called from MYCOLUMNINIT(412) in Demo2.prg Called from MYBRW(339) in Demo2.prg Called from MAIN(192) in Demo2.prg[/pre2] По коду для удобства вывода итогов было сделано так: [pre2]// инициализация колонок таблицы для фильтра/итого по вирт.колонкам STATIC FUNCTION myColumnInit( oBrw ) LOCAL oCol WITH OBJECT oBrw FOR EACH oCol IN :aColumns // Init Cargo в колонке oCol:Cargo := oKeyData() oCol:Cargo:nSum := 0 oCol:Cargo:aVirt := Array((:cAlias)->( LastRec() )) // строка 412 AFill(oCol:Cargo:aVirt, 0)[/pre2] Наверное это нужно убрать для этого случая и использовать итого только для виртуальных колонок, чтобы не налетать на

PSP: Andrey пишет: oCol:Cargo:aVirt := Array((:cAlias)->( LastRec() )) // строка 412 ... Наверное это нужно убрать для этого случая и Нужно придумать другой алгоритм, в котором не будет использования массивов и memio.

Andrey: PSP пишет: Нужно придумать другой алгоритм, в котором не будет использования массивов и memio. Ну это сложно сделать без массивов. Тем более memio вроде классная штука, только пользоваться её надо научиться. Я понял, что большие базы делать не надо, а делать как Сергей советует небольшие базы. А массивы такие как я делал в своём алгоритме тоже нельзя делать, нужно уменьшать их и думать для чего их использовать, т.е. лишние не используемые массивы плодить не надо. В данном случае у меня было так. Рабочий пример, не вылетающий на моих рабочих базах - выслал Григорию для библиотеки. Попробовать пример можно с любыми базами - Demo2.exe Test.dbf Но это пример просто учебный с двумя ТСБ и виртуальными колонками, реальный пример для сравнения баз пока только делаю.

Pasha: Andrey пишет: Делал просто пример под задачу сравнения двух dbf и показ отличий в ТСБ. Думал сделать показ различия строк и колонок цветами, а цвета загнать в массив или во временную базу. У меня в утилите dbedit как раз есть функция сравнения двух dbf, без использования промежуточного массива. Там цикл по первому dbf, сравнение каждой записи со вторым с записью различий в выходной массив. В массив заносятся только различия

SergKis: Pasha пишет Там цикл по первому dbf, сравнение каждой записи со вторым с записью различий в выходной массив. В массив заносятся только различия У Андрея не программа сравнения, а скорее два цветных отчета (таблицы) на одном окне с 6-ю запросами к одной базе, которые результат помещают в новые виртуальные колонки (6 штук можно больше делать), обозначая цветами, в соответствии с данными и алгоритмами, каждой колонки. По виртуальным полям можно фильтровать полученный результат как по одной колонке, так и по всем с получением соответствующих итогов, работая на 2-х таблицах.

Andrey: SergKis пишет: У Андрея не программа сравнения, а скорее два цветных отчета (таблицы) ... Да это точно. Просто нужно юзеру показать различия допустим текущей базы и что было несколько месяцев назад. А то вечно стенания, то данные пропали, то никто данные не трогал, а они другие и т.д. Да и самому понятней становиться когда перед глазами изменения, как в WinMerge.

PSP: Andrey пишет: Ну это сложно сделать без массивов. Тем более memio вроде классная штука, только пользоваться её надо научиться. Каждый инструмент имеет ограниченный круг применения. Даже самой дорогой золотой ложкой траншею трудно выкопать. Сломается))

SergKis: Andrey пишет Просто нужно юзеру показать различия допустим текущей базы и что было несколько месяцев назад Это частный случай, более общий, на мой взгляд, получение данных за периоды по 6 показателям (можно больше) для сравнения, например прошлый месяц (1 таблица тсб) и текущий (2 таблица тсб), прошлый год и тек. год, кварталы, и т.д. для анализа и сравнения

Pasha: В конце концов, есть же диспетчер задач. Достаточно оценить, сколько программа берет памяти в спокойном состоянии, пусть это будет 10-20М, и в возбужденном. Если память будет зашкаливать, это значит, что "что-то я делаю не так"



полная версия страницы