Lua Memory Allocator and Memory Check

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Lua Memory Allocator and Memory Check

Santosh Kadam
Hi, 

Greetings....

I am doing a few experiments with Lua and Lua memory consumptions. I have following memory allocator function registered with Lua via lua_newstate

lua_State *L = lua_newstate(myl_alloc,NULL);

static void *myl_alloc (void *ud, void *ptr, size_t osize,
                                                size_t nsize)
   {
       (void)ud;  (void)osize;  /* not used */
       if (nsize == 0) {
        memsize-=osize;
//        printf ("Freeing [%ld] bytes, memory size = [%ld] \n",osize, memsize);
         free(ptr);
         return NULL;
       }
       else
        {
/*
        if (memsize > 31000)
        {
          printf ("Memory exceeded 32K \n");
          return NULL;
        }
*/
         memsize+=(nsize-osize);
//         printf ("Allocating new [%ld] bytes,old size = [%ld], total = [%ld] \n",nsize, osize, memsize);
         return realloc(ptr, nsize);
        }
     }

This function adds / subtracts the memory size used by Lua and stores the same in the global memsize variable. 

At the end of the execution i.e. When I call lua_close - I expected to get a "zero" printed by the memsize but I am getting a negative number. 
----------
The memory size = [-1165]
----------

Why is it that the memory count negative ? 

I am pasting the code .....

Thanks and Regards
Santosh



Below is my script ..

------------------
function add(a, b)
    a=10
    b=20
    print (a+b)
--    collectgarbage("collect")
    print(collectgarbage("count"))
    print ("Add - after garbage collect")
    return a+b
end

function subt(a, b)
    a=10
    b=20
    print (b-a)
    print ("memory in subt")
 --   collectgarbage("collect")
    print(collectgarbage("count"))
    return b-a
end

add (3,4)
---------------------

And the complete program is as below...

---------------
#include"lua.h"
#include"lauxlib.h"
#include"lualib.h"
#include<stdlib.h>
#include<stdio.h>

long memsize = 0;

static void *myl_alloc (void *ud, void *ptr, size_t osize,
                                                size_t nsize);
int main ()
{
  char str [80], *str1, *str2;
  int i;

  FILE *f = fopen("./add.lua", "rb");
  fseek(f, 0, SEEK_END);
  long fsize = ftell(f);
  fseek(f, 0, SEEK_SET);

  str1 = malloc(fsize + 1);
  fread(str1, fsize, 1, f);
  fclose(f);
  printf ("Add String = \n[%s]\n",str1);

  FILE *f1 = fopen("./subt.lua", "rb");
  fseek(f1, 0, SEEK_END);
  fsize = ftell(f1);
  fseek(f1, 0, SEEK_SET);

  str2 = malloc(fsize + 1);
  fread(str2, fsize, 1, f1);
  fclose(f1);

  printf ("Factorial String = \n[%s]\n",str2);
  //lua_State *L = luaL_newstate();
  lua_State *L = lua_newstate(myl_alloc,NULL);
  luaL_openlibs(L);
  luaL_loadstring(L, str1);
  
/*
  if (lua_pcall(L,0, 1, 0)) {
    printf ("Something went wrong during execution [%s\n",lua_tostring(L, -1)) ;
    lua_pop(L,1);
  }
*/


  if (lua_pcall(L,0, LUA_MULTRET, 0)) {
            printf ("Something went wrong during execution [%s\n",lua_tostring(L, -1)) ;
            lua_pop(L,1);
  }


  do
  {
     printf ("Enter the operation: ");
     scanf ("%79s",str);  
   //  printf ("Memory before loadString = [%ld]\n",memsize);
     if (strcmp (str, "add") == 0)
      {
   //  printf ("Memory after loadString = [%ld]\n",memsize);


          lua_getglobal(L, "add");
          lua_pushnumber(L, 5);
          lua_pushnumber(L, 5);

          if (lua_pcall(L,2, 1, 0)) {
            printf ("Something went wrong during execution [%s\n",lua_tostring(L, -1)) ;
            lua_pop(L,1);
          }
          lua_pop(L,1);
    // printf ("Memory after pcall = [%ld]\n",memsize);

      }

     if (strcmp (str, "subt") == 0)
      {
        luaL_loadstring(L, str2);
          lua_getglobal(L, "subt");
          lua_pushnumber(L, 5);
          lua_pushnumber(L, 5);
        printf ("Inside subt [%s]\n", lua_tostring(L, -1));
          if (lua_pcall(L,2, 1, 0)) {
            printf ("Something went wrong during execution [%s\n",lua_tostring(L, -1)) ;
            lua_pop(L,1);
          }
            lua_pop(L,1);

      }

     printf ("You have entered %s \n",str);
  } while (strcmp (str, "quit"));
  
  lua_close(L);
printf ("The memory size = [%ld]\n",memsize);
  return 0;
}


static void *myl_alloc (void *ud, void *ptr, size_t osize,
                                                size_t nsize)
   {
       (void)ud;  (void)osize;  /* not used */
       if (nsize == 0) {
        memsize-=osize;
//        printf ("Freeing [%ld] bytes, memory size = [%ld] \n",osize, memsize);
         free(ptr);
         return NULL;
       }
       else
        {
/*
        if (memsize > 31000)
        {
          printf ("Memory exceeded 32K \n");
          return NULL;
        }
*/
         memsize+=(nsize-osize);
     //   printf ("Allocating new [%ld] bytes,old size = [%ld], total = [%ld] \n",nsize, osize, memsize);
         return realloc(ptr, nsize);
        }
     }
--------------

Reply | Threaded
Open this post in threaded view
|

Re: Lua Memory Allocator and Memory Check

Rena
On Mon, Nov 24, 2014 at 1:02 AM, Santosh Kadam <[hidden email]> wrote:

> Hi,
>
> Greetings....
>
> I am doing a few experiments with Lua and Lua memory consumptions. I have
> following memory allocator function registered with Lua via lua_newstate
>
> lua_State *L = lua_newstate(myl_alloc,NULL);
>
> static void *myl_alloc (void *ud, void *ptr, size_t osize,
>                                                 size_t nsize)
>    {
>        (void)ud;  (void)osize;  /* not used */
>        if (nsize == 0) {
>         memsize-=osize;
> //        printf ("Freeing [%ld] bytes, memory size = [%ld] \n",osize,
> memsize);
>          free(ptr);
>          return NULL;
>        }
>        else
>         {
> /*
>         if (memsize > 31000)
>         {
>           printf ("Memory exceeded 32K \n");
>           return NULL;
>         }
> */
>          memsize+=(nsize-osize);
> //         printf ("Allocating new [%ld] bytes,old size = [%ld], total =
> [%ld] \n",nsize, osize, memsize);
>          return realloc(ptr, nsize);
>         }
>      }
>
> This function adds / subtracts the memory size used by Lua and stores the
> same in the global memsize variable.
>
> At the end of the execution i.e. When I call lua_close - I expected to get a
> "zero" printed by the memsize but I am getting a negative number.
> ----------
> The memory size = [-1165]
> ----------
>
> Why is it that the memory count negative ?
>
> I am pasting the code .....
>
> Thanks and Regards
> Santosh
>
>
>
> Below is my script ..
>
> ------------------
> function add(a, b)
>     a=10
>     b=20
>     print (a+b)
> --    collectgarbage("collect")
>     print(collectgarbage("count"))
>     print ("Add - after garbage collect")
>     return a+b
> end
>
> function subt(a, b)
>     a=10
>     b=20
>     print (b-a)
>     print ("memory in subt")
>  --   collectgarbage("collect")
>     print(collectgarbage("count"))
>     return b-a
> end
>
> add (3,4)
> ---------------------
>
> And the complete program is as below...
>
> ---------------
> #include"lua.h"
> #include"lauxlib.h"
> #include"lualib.h"
> #include<stdlib.h>
> #include<stdio.h>
>
> long memsize = 0;
>
> static void *myl_alloc (void *ud, void *ptr, size_t osize,
>                                                 size_t nsize);
> int main ()
> {
>   char str [80], *str1, *str2;
>   int i;
>
>   FILE *f = fopen("./add.lua", "rb");
>   fseek(f, 0, SEEK_END);
>   long fsize = ftell(f);
>   fseek(f, 0, SEEK_SET);
>
>   str1 = malloc(fsize + 1);
>   fread(str1, fsize, 1, f);
>   fclose(f);
>   printf ("Add String = \n[%s]\n",str1);
>
>   FILE *f1 = fopen("./subt.lua", "rb");
>   fseek(f1, 0, SEEK_END);
>   fsize = ftell(f1);
>   fseek(f1, 0, SEEK_SET);
>
>   str2 = malloc(fsize + 1);
>   fread(str2, fsize, 1, f1);
>   fclose(f1);
>
>   printf ("Factorial String = \n[%s]\n",str2);
>   //lua_State *L = luaL_newstate();
>   lua_State *L = lua_newstate(myl_alloc,NULL);
>   luaL_openlibs(L);
>   luaL_loadstring(L, str1);
>
> /*
>   if (lua_pcall(L,0, 1, 0)) {
>     printf ("Something went wrong during execution [%s\n",lua_tostring(L,
> -1)) ;
>     lua_pop(L,1);
>   }
> */
>
>
>   if (lua_pcall(L,0, LUA_MULTRET, 0)) {
>             printf ("Something went wrong during execution
> [%s\n",lua_tostring(L, -1)) ;
>             lua_pop(L,1);
>   }
>
>
>   do
>   {
>      printf ("Enter the operation: ");
>      scanf ("%79s",str);
>    //  printf ("Memory before loadString = [%ld]\n",memsize);
>      if (strcmp (str, "add") == 0)
>       {
>    //  printf ("Memory after loadString = [%ld]\n",memsize);
>
>
>           lua_getglobal(L, "add");
>           lua_pushnumber(L, 5);
>           lua_pushnumber(L, 5);
>
>           if (lua_pcall(L,2, 1, 0)) {
>             printf ("Something went wrong during execution
> [%s\n",lua_tostring(L, -1)) ;
>             lua_pop(L,1);
>           }
>           lua_pop(L,1);
>     // printf ("Memory after pcall = [%ld]\n",memsize);
>
>       }
>
>      if (strcmp (str, "subt") == 0)
>       {
>         luaL_loadstring(L, str2);
>           lua_getglobal(L, "subt");
>           lua_pushnumber(L, 5);
>           lua_pushnumber(L, 5);
>         printf ("Inside subt [%s]\n", lua_tostring(L, -1));
>           if (lua_pcall(L,2, 1, 0)) {
>             printf ("Something went wrong during execution
> [%s\n",lua_tostring(L, -1)) ;
>             lua_pop(L,1);
>           }
>             lua_pop(L,1);
>
>       }
>
>      printf ("You have entered %s \n",str);
>   } while (strcmp (str, "quit"));
>
>   lua_close(L);
> printf ("The memory size = [%ld]\n",memsize);
>   return 0;
> }
>
>
> static void *myl_alloc (void *ud, void *ptr, size_t osize,
>                                                 size_t nsize)
>    {
>        (void)ud;  (void)osize;  /* not used */
>        if (nsize == 0) {
>         memsize-=osize;
> //        printf ("Freeing [%ld] bytes, memory size = [%ld] \n",osize,
> memsize);
>          free(ptr);
>          return NULL;
>        }
>        else
>         {
> /*
>         if (memsize > 31000)
>         {
>           printf ("Memory exceeded 32K \n");
>           return NULL;
>         }
> */
>          memsize+=(nsize-osize);
>      //   printf ("Allocating new [%ld] bytes,old size = [%ld], total =
> [%ld] \n",nsize, osize, memsize);
>          return realloc(ptr, nsize);
>         }
>      }
> --------------
>

It looks like you aren't accounting for the case when ptr == NULL. In
that case, osize encodes information about the type of object being
allocated, so you don't want to subtract it from memsize. See
http://www.lua.org/manual/5.2/manual.html#lua_Alloc

(also, your message got flagged as spam for some reason.)

--
Sent from my Game Boy.

Reply | Threaded
Open this post in threaded view
|

Re: Lua Memory Allocator and Memory Check

Peter Pimley
In reply to this post by Santosh Kadam
Your allocator function needs to handle the case where nsize is nonzero, but ptr is null.  This is the case for a new allocation, rather than a resize of an existing block.  In this case, osize represents something else (see below), and you don't want to do the "memsize +=" line.

From the manual:

"When ptr is NULL, osize encodes the kind of object that Lua is allocating. osize is any of LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, or LUA_TTHREAD when (and only when) Lua is creating a new object of that type. When osize is some other value, Lua is allocating memory for something else."


On 24 November 2014 at 06:02, Santosh Kadam <[hidden email]> wrote:
Hi, 

Greetings....

I am doing a few experiments with Lua and Lua memory consumptions. I have following memory allocator function registered with Lua via lua_newstate

lua_State *L = lua_newstate(myl_alloc,NULL);

static void *myl_alloc (void *ud, void *ptr, size_t osize,
                                                size_t nsize)
   {
       (void)ud;  (void)osize;  /* not used */
       if (nsize == 0) {
        memsize-=osize;
//        printf ("Freeing [%ld] bytes, memory size = [%ld] \n",osize, memsize);
         free(ptr);
         return NULL;
       }
       else
        {
/*
        if (memsize > 31000)
        {
          printf ("Memory exceeded 32K \n");
          return NULL;
        }
*/
         memsize+=(nsize-osize);
//         printf ("Allocating new [%ld] bytes,old size = [%ld], total = [%ld] \n",nsize, osize, memsize);
         return realloc(ptr, nsize);
        }
     }

This function adds / subtracts the memory size used by Lua and stores the same in the global memsize variable. 

At the end of the execution i.e. When I call lua_close - I expected to get a "zero" printed by the memsize but I am getting a negative number. 
----------
The memory size = [-1165]
----------

Why is it that the memory count negative ? 

I am pasting the code .....

Thanks and Regards
Santosh



Below is my script ..

------------------
function add(a, b)
    a=10
    b=20
    print (a+b)
--    collectgarbage("collect")
    print(collectgarbage("count"))
    print ("Add - after garbage collect")
    return a+b
end

function subt(a, b)
    a=10
    b=20
    print (b-a)
    print ("memory in subt")
 --   collectgarbage("collect")
    print(collectgarbage("count"))
    return b-a
end

add (3,4)
---------------------

And the complete program is as below...

---------------
#include"lua.h"
#include"lauxlib.h"
#include"lualib.h"
#include<stdlib.h>
#include<stdio.h>

long memsize = 0;

static void *myl_alloc (void *ud, void *ptr, size_t osize,
                                                size_t nsize);
int main ()
{
  char str [80], *str1, *str2;
  int i;

  FILE *f = fopen("./add.lua", "rb");
  fseek(f, 0, SEEK_END);
  long fsize = ftell(f);
  fseek(f, 0, SEEK_SET);

  str1 = malloc(fsize + 1);
  fread(str1, fsize, 1, f);
  fclose(f);
  printf ("Add String = \n[%s]\n",str1);

  FILE *f1 = fopen("./subt.lua", "rb");
  fseek(f1, 0, SEEK_END);
  fsize = ftell(f1);
  fseek(f1, 0, SEEK_SET);

  str2 = malloc(fsize + 1);
  fread(str2, fsize, 1, f1);
  fclose(f1);

  printf ("Factorial String = \n[%s]\n",str2);
  //lua_State *L = luaL_newstate();
  lua_State *L = lua_newstate(myl_alloc,NULL);
  luaL_openlibs(L);
  luaL_loadstring(L, str1);
  
/*
  if (lua_pcall(L,0, 1, 0)) {
    printf ("Something went wrong during execution [%s\n",lua_tostring(L, -1)) ;
    lua_pop(L,1);
  }
*/


  if (lua_pcall(L,0, LUA_MULTRET, 0)) {
            printf ("Something went wrong during execution [%s\n",lua_tostring(L, -1)) ;
            lua_pop(L,1);
  }


  do
  {
     printf ("Enter the operation: ");
     scanf ("%79s",str);  
   //  printf ("Memory before loadString = [%ld]\n",memsize);
     if (strcmp (str, "add") == 0)
      {
   //  printf ("Memory after loadString = [%ld]\n",memsize);


          lua_getglobal(L, "add");
          lua_pushnumber(L, 5);
          lua_pushnumber(L, 5);

          if (lua_pcall(L,2, 1, 0)) {
            printf ("Something went wrong during execution [%s\n",lua_tostring(L, -1)) ;
            lua_pop(L,1);
          }
          lua_pop(L,1);
    // printf ("Memory after pcall = [%ld]\n",memsize);

      }

     if (strcmp (str, "subt") == 0)
      {
        luaL_loadstring(L, str2);
          lua_getglobal(L, "subt");
          lua_pushnumber(L, 5);
          lua_pushnumber(L, 5);
        printf ("Inside subt [%s]\n", lua_tostring(L, -1));
          if (lua_pcall(L,2, 1, 0)) {
            printf ("Something went wrong during execution [%s\n",lua_tostring(L, -1)) ;
            lua_pop(L,1);
          }
            lua_pop(L,1);

      }

     printf ("You have entered %s \n",str);
  } while (strcmp (str, "quit"));
  
  lua_close(L);
printf ("The memory size = [%ld]\n",memsize);
  return 0;
}


static void *myl_alloc (void *ud, void *ptr, size_t osize,
                                                size_t nsize)
   {
       (void)ud;  (void)osize;  /* not used */
       if (nsize == 0) {
        memsize-=osize;
//        printf ("Freeing [%ld] bytes, memory size = [%ld] \n",osize, memsize);
         free(ptr);
         return NULL;
       }
       else
        {
/*
        if (memsize > 31000)
        {
          printf ("Memory exceeded 32K \n");
          return NULL;
        }
*/
         memsize+=(nsize-osize);
     //   printf ("Allocating new [%ld] bytes,old size = [%ld], total = [%ld] \n",nsize, osize, memsize);
         return realloc(ptr, nsize);
        }
     }
--------------