Environment data not fully deallocated.

Help
vranoch
2010-11-23
2012-11-23
  • vranoch

    vranoch - 2010-11-23

    Hello after some time again,

    I meet above warning I try to release environment in case an error occurred while processing rules (e.g. in some user function or even when user break was issued). What does this exactly mean? Does it imply a memory leak or the following free() call releases any allocated memory correctly?    If not, what should be done to ensure a correct memory deallocation in case of exception in evaluation of rules?

    thanks  Vranoch

     
  • vranoch

    vranoch - 2010-11-24

    Hello, I did some investigation and find out, that in this case it really causes a memory leak - allocated memory seems not to be centrally registered so that it could be centrally deallocated - is that correct? Or is there any mean to deallocate all allocated memory?

    thanks Vranoch

     
  • Gary Riley

    Gary Riley - 2010-12-01

    Memory is centrally registered. That's why you're getting the error message when you release the environment. CLIPS tracks the number of allocations made. Which version of CLIPS are you using? Are you attempting to release the environment while CLIPS is running?

     
  • vranoch

    vranoch - 2010-12-01

    Hello, I am using CLIPS 6.24 I guess. I did some further investigation. Memory leak happens in the case when during execution of rules some error occurs (e.g. division by zero in a deffunction) Then the run() function exits and in the consequent DestroyEnvironment It issues the leak. I made a workaround by hoking my own allocated memory register into genalloc(), genfree(), through which I can force a release of all allocated blocks.

    As I found, there are three sources of leeking:
    1) unused memory blocks registereds in MemoryTable - in DestroyEnvironment(), there is only free (MemoryTable), not of it's content
    2) used memory blocks not registered in MemoryTable dynamically allocated during load() and run()
    3) memory blocks allocated within InitializeEnvironment() - there are lots of allocations (may be they are covered by 2)
    I guess the soulution may be based on some evidence of all allocated blocks (not only unused) and on deallocating all of them in DestroyEnvironment

    Thanks Vranoch 

     
  • Gary Riley

    Gary Riley - 2010-12-02

    Use this within DestroyEnvironment to let you know how much memory is not being deallocated:

          printf("\n Environment data not fully deallocated.\n");
          printf("\n MemoryAmount = %ld.\n",(long) theMemData->MemoryAmount);
          printf("\n MemoryCalls = %ld.\n",(long) theMemData->MemoryCalls);

    Freeing of memory is being performed by this block of code in DestroyEnvironment:

       for (i = 0; i < MAXIMUM_ENVIRONMENT_POSITIONS; i++)
         {
          if (theEnvironment->cleanupFunctions_ != NULL)
            { (*theEnvironment->cleanupFunctions)(theEnvironment); }
         }

    Any genalloc call without an accompanying genfree will result in environment data not being fully deallocated when the environment is destroyed. That's the purpose of the cleanup functions. So if you're using genalloc and an error occurs, your error handling code needs to account for this and deallocate the memory. _

     
  • vranoch

    vranoch - 2010-12-03

    When I try run the following program:

    (deffunction FN1 ( ?arg0 )
    (bind ?x (/ 1 0))
    (return 1)
    )

    (defrule XY ""
    =>
       (FN1 1)
    )

    through the following C code:

    void* pEnv = kmxCreateEnvironmentEx(pszConnectionString);
    if(pEnv)
    {
    int result, result1;
            SetUpRouters(pEnv);
    result = kmxLoad(pEnv,pszFile);

    if(1 == result)
    {
    kmxReset(pEnv);
    unsigned long l;
    if(AddFact(pEnv,pszFileFacts))
    {
    l = kmxGetNumberOfFacts(pEnv);
    try
            {
    int halt = kmxGetHaltExecution (pEnv);
                        kmxRun(pEnv,-1, MAX_ERROR_TXT_BUF_LEN, errorBuf);

    halt = kmxGetHaltExecution (pEnv);
    int err = kmxGetEvaluationError (pEnv);
    }
    catch(_com_error& err)
            {
    // exception handling
    }
    catch(…)
    {
    // exception handling
    }
    }
    }
    kmxDeleteRouter(pEnv,_T("kmxStdIO"));
        kmxDestroyEnvironment(pEnv);
    }

    I get the following in the DestroyEnvironment() call:
    Environment data not fully deallocated.
    MemoryAmount = 79211.
    MemoryCalls = 3542.

    It is a memory allocated by intrnal CLIPS structures, not by any user functions, how should I clean it up through a CleanupFunction() - or, am I doing something wrong?

    Thanks Vranoch

     
  • Gary Riley

    Gary Riley - 2010-12-04

    Try running your program with the following code:

       theEnv = CreateEnvironment();

       EnvLoad(theEnv,"bug.clp");
       EnvReset(theEnv);
       EnvRun(theEnv,-1);
       DestroyEnvironment(theEnv);

    Then try running it with the kmx… equivalent code you're using. I can't reproduce the problem using the core CLIPS source code, so you'll need to determine if the problem is with the extensions you're using.

     
  • macky miro

    macky miro - 2010-12-05

    wow you guys great ahm can i ask? how did you run CLIPS on C ??? did you have an extension??/ want to know bout that thing

     
  • vranoch

    vranoch - 2010-12-08

    Hello Gary,

    I tried the "naked" version and I get the same problem. I am using CLIPS on Windows platform, compiled do DLL which is then called either from C++ or .NET. Shall I pack my sources and send them to You? Would that help?

    thanks Vranoch

     
  • Gary Riley

    Gary Riley - 2010-12-09

    Yes, send your sources to me at clips2010@swbell.net

     
  • Gary Riley

    Gary Riley - 2011-01-02

    I wasn't able to get the project you sent working (using Visual C++ Express 2010), but I was able to replicate the problem using just the CLIPS source without the DLL wrapper. Try using the 6.24 source code (https://sourceforge.net/projects/clipsrules/files/CLIPS/6.24/) in your project rather than the 6.23 source code. Specifically, you want the fix in the EnvReleaseMem function in memalloc.c where the line

          if (((amount > maximum) && (maximum > 0)) || EvaluationData(theEnv)->HaltExecution)

    is replaced by

          if ((amount > maximum) && (maximum > 0))

     
  • vranoch

    vranoch - 2011-01-12

    Hello Gary,

    thanks a lot for this fix. It really helped. I implemented the fix to my current code since first I do not have time now to change the clips base and second, I tried to do it some time ago and that time I found some bugs comparing to my current version (unfortunately I do not remember what it was - it is far ago already). I may try it once I have more time.

    Anyway, the fix helps but I still recognize some "Environment data not fully deallocated" when profiling is enabled. I happens on more complex programs and I had not enough time to separate the problem so far. When I do, I will let You know.

    thanks Vranoch

     

Log in to post a comment.