Unable to allocate memory for result from BASE64-ENCODE func

Posted by jbijker on 03-Jun-2016 05:55

Hi everyone


We're hitting an interesting "Unable to allocate memory for result from BASE64-ENCODE function (12118)" error when doing the following operation:

  METHOD PUBLIC LOGICAL storeDocument
    (INPUT ipcDocumentFilename AS CHARACTER)

    DEFINE VARIABLE mDocument AS MEMPTR      NO-UNDO.
    DEFINE VARIABLE cDocument AS LONGCHAR    NO-UNDO.
    
    FILE-INFO:FILENAME = ipcDocumentFileName.
    SET-SIZE(mDocument) = FILE-INFO:FILE-SIZE.
    COPY-LOB FROM FILE ipcDocumentFilename TO mDocument NO-CONVERT.
    ASSIGN cDocument = BASE64-ENCODE(mDocument).

    .... store cDocument somewhere on a repository ...

    FINALLY:
      SET-SIZE(mDocument) = 0.
    END FINALLY.
  END METHOD.

This method normally works without any issue. But we had an interesting case where the input file was almost 600MB and in this case it's failing on the BASE64-ENCODE function with the error as above. We've reproduced this on Unix 64-bit and Windows 32-bit (OE11.3). In both instances there were plenty of memory available, below is for the Unix box:

 free -m
             total       used       free     shared    buffers     cached
Mem:         48297      48197        100          0         13      18584
-/+ buffers/cache:      29600      18697
Swap:        16386      16386          0

Any ideas how to get past this?

Posted by bronco on 03-Jun-2016 07:45

Well, you're trying to address about approx 1,4GB in one method. That's quite a lot. I always say: when you want to eat an elephant slice it in little pieces. The problem is, I wouldn't know a way to partially read your 600MB file. Otherwise:

define variable m1 as memptr no-undo.

define variable m2 as memptr no-undo.

define variable m3 as memptr no-undo.

set-size(m1) = 3.

put-byte(m1, 1) = 30.

put-byte(m1, 2) = 31.

put-byte(m1, 3) = 32.

set-size(m2) = 3.

put-byte(m2, 1) = 40.

put-byte(m2, 2) = 41.

put-byte(m2, 3) = 42.

set-size(m3) = 6.

put-byte(m3, 1) = 30.

put-byte(m3, 2) = 31.

put-byte(m3, 3) = 32.

put-byte(m3, 4) = 40.

put-byte(m3, 5) = 41.

put-byte(m3, 6) = 42.

message

 base64-encode(m1) + base64-encode(m2) = base64-encode(m3)   // = true

 .

PS always encode x*3 bytes at a time.

All Replies

Posted by goo on 03-Jun-2016 06:17

This has to be food for TechSupport.

Posted by Brian K. Maher on 03-Jun-2016 07:06

Please open a case with Tech Support for this and provide a way to reproduce the behavior.

Posted by bronco on 03-Jun-2016 07:45

Well, you're trying to address about approx 1,4GB in one method. That's quite a lot. I always say: when you want to eat an elephant slice it in little pieces. The problem is, I wouldn't know a way to partially read your 600MB file. Otherwise:

define variable m1 as memptr no-undo.

define variable m2 as memptr no-undo.

define variable m3 as memptr no-undo.

set-size(m1) = 3.

put-byte(m1, 1) = 30.

put-byte(m1, 2) = 31.

put-byte(m1, 3) = 32.

set-size(m2) = 3.

put-byte(m2, 1) = 40.

put-byte(m2, 2) = 41.

put-byte(m2, 3) = 42.

set-size(m3) = 6.

put-byte(m3, 1) = 30.

put-byte(m3, 2) = 31.

put-byte(m3, 3) = 32.

put-byte(m3, 4) = 40.

put-byte(m3, 5) = 41.

put-byte(m3, 6) = 42.

message

 base64-encode(m1) + base64-encode(m2) = base64-encode(m3)   // = true

 .

PS always encode x*3 bytes at a time.

Posted by jbijker on 03-Jun-2016 08:17

Thanks Bronco, gonna try this and hope for the best.

Posted by Brian K. Maher on 06-Jun-2016 11:52

JBijker,
 
I’m not surprised for the 32-bit version since you realistically have 2 gig usable.  For the 64-bit version I expect there is a memory consumption limit (ulimit). 
 
Brian

Posted by gus on 06-Jun-2016 11:52

if you are running 32-bit executables then no wonder it fails.

You need to allocate 600 MB of memory in one contiguous chunk to read in the data and then another 900 MB contiguous chunk to hold the base 64 encoded version.

This thread is closed