Search code examples
memory-leaksibm-doors

How to measure memory consumption of DXL script?


Finding out if your script has a significant memory leak might be of interest even before you run into serious trouble. Unfortunately, I was not able to find out how to measure the current stack/heap size or "string table" size (see http://www.smartdxl.com/content/?p=481). Can anybody help?

Related question: Predicting DXL Memory and CPU Usage


Solution

  • The biggest memory "leak" would be open modules that are no longer being used. So of course you should be closing those.

    Next you want to keep the production of new strings to a minimum since each new one creates an entry in a string table. You can find an excellent dissertation on that by Mathias Mamsch here: https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014886977&ps=25

    Finally, data types that have create/delete methods can eat up memory if they are not being deleted. To find unreleased instances, I use some memory functions originally created by Mathias Mamsch. The link I have back to his post no longer works, but here are the functions that I use:

    //< Memory Functions [Memory.inc]
    /*
    Code adapted from forum post by Mathias Mamsch:
    https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014830975
    */
    
    int *::+(int *ptr, int ofs)
    {
        int *rtn = ptr
        rtn += ofs
        return(rtn)
    }
    
    int *::@(int *ptr, int ofs)
    {
        int adr = *(ptr + ofs)
        int *rtn = addr_(adr)
        return(rtn)
    }
    
    int *mbn(int *ptr)
    {
        return(ptr @ 0x74)
    }
    
    int *nnn(int *ptr)
    {
        return(ptr @ 8)
    }
    
    int *ccp()
    {
        DB db = create("")
        int *ptr = addr_(db)
        int *rtn = ptr @ 48
        destroy(db)
        return(rtn)
    }
    
    int allocatedObjects()
    {
        int cnt = 0
        int *mb = mbn(ccp())
        while(!null mb) { mb = nnn(mb) ; cnt++ }
        return(cnt)
    }
    

    I'm pretty sure I changed the function and variable names from the original posted code, so be aware of that if you ever come across his original code. And don't ask me about the hard-coded numbers... Mathias explained them in the post and I don't recall the explanation.

    Here's how you would use the code:

    //< Test of Memory.inc
    /*
    */
    pragma encoding, "UTF-8"
    
    #include <stdlib/Memory.inc>
    
    pragma runLim, 0
    
    int numallobj = allocatedObjects()
    print numallobj "\n"
    
    Skip skp = null Skip
    
    numallobj = allocatedObjects()
    print numallobj "\n"
    
    skp = create()
    
    numallobj = allocatedObjects()
    print numallobj "\n"
    
    delete(skp)
    
    numallobj = allocatedObjects()
    print numallobj "\n"
    
    /*
    Output should be:
    0
    0
    1
    0
    */