Results 1 to 10 of 13

Thread: OOM Error on 32 Bit before hitting 2GB boundary?

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1

    Default OOM Error on 32 Bit before hitting 2GB boundary?

    Hi,

    I had reported this to Harm before, but as I got no reply... sharing this with the community.
    Perhaps I'm overlooking something silly (wouldn''t be the first time)

    This is on DataFlex 20.1 (latest), 32 bit.

    The following code works on 64 bit and the project now also works fine under 64 bit, so one could argue that this is all hypothetical.
    However I'm wondering why I'm getting a Out Of Memory error (OOM Error) when using this.

    Demo Code:
    Code:
    Use Windows.pkg
    Use Dfpanel.pkg
    Use Batchdd.pkg
    Use File_dlg.pkg
    
    Object oMain is a Panel
      Set Size to 100 300
      Set Label to "Base64 OOM Error demo"
      
      Use seq_chnl.pkg
      Use cCharTranslate.pkg
      
      Object oCharTranslate is a cCharTranslate
      End_Object
      
      Object oBase64 is a cObject
    
        Function BinaryEncodeFileToUChar String sFileSource Returns UChar[]
          UChar[] ucFile
          UChar[] ucEncoded
          
          Boolean bExists
          Integer iChIn 
          
          If (sFileSource <> "") Begin
              Get Seq_New_Channel to iChIn
              If (iChIn <> DF_SEQ_CHANNEL_NOT_AVAILABLE) Begin
             
                Direct_Input channel iChIn ("BINARY:" + sFileSource)      
                  Read_Block channel iChIn ucFile -1
                Close_Input channel iChIn
                Send Seq_Release_Channel iChIn 
                  
                Get Base64EncodeUCharArray of oCharTranslate ucFile to ucEncoded   /// <--- crashing here
              End 
          End
          
          Function_Return ucEncoded
        End_Function 
      End_Object
      
      Object oXmlUpload_bp is a BusinessProcess
        Function UploadFile String sFileName Returns Boolean
          UChar[] ucEncoded
          Get BinaryEncodeFileToUChar  of oBase64 sFileName to ucEncoded 
          // more code here... for the actual chunked upload
        End_Function
    
      End_Object
    
      Object oOpenDialog is a OpenDialog
        Set Dialog_Caption to "Select a file"
    
        Set CreatePrompt_State  to False
        Set FileMustExist_State to True
        Set NoChangeDir_State   to True
        Set Filter_String to 'All Files|*.*'
      End_Object
      
      Object oFileForm is a Form
        Set Label to "Select File:"
        Set Location to 10 75
        Set Size to 13 150
        Set peAnchors to anBottomLeftRight
        Set Prompt_Button_Mode to pb_PromptOn
        Set Form_Button_Bitmap Item 0 to "GlobePlug.ico"
        
        Procedure Prompt
          Boolean bOk
          String  sFileName
        
          Get Show_Dialog of oOpenDialog to bOk
          If (bOk) Begin
            Get File_Name of oOpenDialog to sFileName
            Set Value              to sFileName    // as we do not want to save that
            Set Item_Changed_State to True         // in here.
          End
        End_Procedure
      End_Object
    
      Object oUploadButton is a Button
        Set Label to "Upload file"
        Set Size to 14 62
        Set Location to 45 122
        Set peAnchors to anBottomRight
    
        Procedure OnClick
          String  sFileName
          Boolean bExists
    
          Get Value of oFileForm to sFileName
          Send doUploadFile sFileName
        End_Procedure
      End_Object
      
      Procedure doUploadFile String sFileName
        Boolean bUploadOk
        String  sMsg
        
        Send Cursor_Wait of Cursor_Control
    
        Get UploadFile of oXmlUpload_Bp sFileName to bUploadOk
        
        Send Cursor_Ready of Cursor_Control
    
        If (bUploadOk) Move (sFileName*"upload to the server successfully.\n" ) to sMsg
        Else Move (sFileName*"upload to the server FAILED. Please try again\n" ) to sMsg
    
        Send Info_box sMsg "Upload status"
      End_Procedure
      
    End_Object
    
    Start_UI
    The code above comes from a heavily trimmed down webservice client to upload any kind of file to a DataFlex webservice.

    One of the things I tested it with was the 230MB sized DataFlex installer.. Not because we need to upload that kind of file, but because it was available and I wanted to see the performance and/or see if my code had an obvious issue in the webservice somewhere.

    So it's not exactly a small file to test with.

    However.. it isn't close to a 2GB limit either.

    As pointed out above it crashes on the line:
    Code:
                Get Base64EncodeUCharArray of oCharTranslate ucFile to ucEncoded   /// <--- crashing here
    If you put a breakpoint in that function itself then the crash is on the ResizeArray line below:
    Click image for larger version. 

Name:	OOM-Error.jpg 
Views:	26 
Size:	102.9 KB 
ID:	15616

    So this is just the code above, no webservice in sight or needed to reproduce this.

    I though I remembered that arrays are passed as pass by reference when used as a parameter to a function and then via "copy on write" expanded when changed. (see discussions from Sonny https://support.dataaccess.com/Forum...n-depth-Part-V ) but I might misremember and I guess I have to reread that blog series again.

    So if what I remember is true, it shouldn't -in theory- use more than 500MB in memory.
    If OTOH all of the data goes onto the stack on every call then I suppose it makes more sense.. but I'm still not counting 2GB.
    To be frank (Frank help?) it would make sense if the data goes on the stack.

    --
    Wil
    Last edited by wila; 23-Aug-2022 at 01:49 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •