ONCODE = 451 Состояние ХРАНЕНИЯ было поднято - PullRequest
0 голосов
/ 09 ноября 2018

Я недавно выпустил обновление для программы отчетов HOST. Наш магазин использует Enterprise PLI.

Я добавил 2 новые структуры, объявленные как BASED. Поэтому я в основном использую инструкцию ALLOC, чтобы выделить необходимое хранилище для структур, а затем передать указатели в Fetchable, чтобы получить некоторые детали, которые мне нужны.

Сбой из-за ошибки хранения во время пилотного запуска в производстве (LEMSG ниже). Он пытался обработать более миллиона записей там, и, похоже, задание практически исчерпано.

IBM0451S  ONCODE=451  The STORAGE condition was raised.                         
From entry point MXXX at compile unit offset +000001EA at entry offset 

Подробнее: IBM0451S

В качестве исправления я выпускаю обновление, чтобы явно добавить БЕСПЛАТНО для хранилища после вызова Fetchable, а также обновил параметр PARION REGION моего JCL до 0M.

Думаю, я бы проверил, видели ли вы подобные ошибки раньше, и у вас есть какие-либо дополнительные мысли. Спасибо.

Вот как выглядит мой последний обновленный код

DECLARES
  =======================================
  DCL                                     
   01 IN_DATA  BASED(IN_PTR),       
     % INCLUDE SYSLIB(XXXXXPAA);          
  DCL                                     
   01 OUT_DATA BASED(OUT_PTR),      
     % INCLUDE SYSLIB(YYYYYPAA);          

  DCL                                     
   01 IN_PTR        PTR;                  
  DCL                                     
   01 OUT_PTR       PTR;  

 ======================================

 The below block of code runs for every record that get processed. The    
 FREE statement is what i now added. I was thinking that because i did 
 not have a FREE before , the ALLOC was basically getting new STOARGE
 everytime it executed that block of code and ran out of storage.



 ALLOC IN_DATA;                              
 ALLOC OUT_DATA;                             

 IN_DATA  = '';                              
 OUT_DATA = '';                              

 IN_DATA.CODE =  'XXX';

 CALL FABCD(IN_PTR,                                 
            OUT_PTR);                               

 IF OUT_DATA.RTRN_CD <= 04 THEN               
   DETAIL_REC.XYZ = OUT_DATA.YYY_CODE;   
 ELSE                                               
  ;                                                 


 FREE IN_DATA;    -------->> What i added now                         
 FREE OUT_DATA;   -------->> What i added now                             

=============================================   

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Помимо проблем с хранилищем, выделение и освобождение хранилища для каждого процесса записи является огромным убийством производительности.

Из показанного вами фрагмента не ясно, а) почему вы изначально указали ALLOC, и б) почему вы думаете, что вам нужен свежий кусок памяти для каждой записи.

Просто выделите структуры локально, передайте указатель на них в функцию.

DCL 01 IN_DATA,       
    % INCLUDE SYSLIB(XXXXXPAA);
DCL 01 OUT_DATA,      
    % INCLUDE SYSLIB(YYYYYPAA);          

DCL IN_PTR        PTR INIT ( ADDR( IN_DATA) );                  
DCL OUT_PTR       PTR INIT ( ADDR( OUT_DATA ) );

В этом случае PL / I будет распределять структуры только один раз, но все же позволит указателям на хранилище переходить в подпрограмму функции.

Я бы также убрал второго убийцу производительности: вероятно, ненужная инициализация структур

IN_DATA  = ‘‘;
OUT_DATA = ‘‘;

Это делает инициализацию поля за полем. Не делайте этого, если у вас нет веских причин.

0 голосов
/ 10 ноября 2018

Это ожидаемое поведение. Исходя из вашего описания, ваш исходный код имел утечку памяти, выделяя хранилище, не освобождая его. Теперь, когда вы добавили код для освобождения выделенной памяти, когда он больше не нужен, вам, скорее всего, не нужен REGION = 0M, хотя, как указано в комментарии, он все равно может не делать то, что вы хотели.

...