luaL_newstate() allocates a Lua state (~2-4 MB with libraries) in the constructor, but there was no destructor to call lua_close(). Every PILuaProgram instance leaked its entire Lua state. Add ~PILuaProgram() that calls lua_close(PRIVATE->lua_state).