Merge pull request #2508 from cuberite/LogLuaMemoryStats
Added LuaState tracker and memory stats logging.
This commit is contained in:
commit
c76a89fbec
@ -42,6 +42,76 @@ const cLuaState::cRet cLuaState::Return = {};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cLuaStateTracker:
|
||||
|
||||
void cLuaStateTracker::Add(cLuaState & a_LuaState)
|
||||
{
|
||||
auto & Instance = Get();
|
||||
cCSLock Lock(Instance.m_CSLuaStates);
|
||||
Instance.m_LuaStates.push_back(&a_LuaState);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaStateTracker::Del(cLuaState & a_LuaState)
|
||||
{
|
||||
auto & Instance = Get();
|
||||
cCSLock Lock(Instance.m_CSLuaStates);
|
||||
Instance.m_LuaStates.erase(
|
||||
std::remove_if(
|
||||
Instance.m_LuaStates.begin(), Instance.m_LuaStates.end(),
|
||||
[&a_LuaState](cLuaStatePtr a_StoredLuaState)
|
||||
{
|
||||
return (&a_LuaState == a_StoredLuaState);
|
||||
}
|
||||
),
|
||||
Instance.m_LuaStates.end()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cLuaStateTracker::GetStats(void)
|
||||
{
|
||||
auto & Instance = Get();
|
||||
cCSLock Lock(Instance.m_CSLuaStates);
|
||||
AString res;
|
||||
int Total = 0;
|
||||
for (auto state: Instance.m_LuaStates)
|
||||
{
|
||||
int Mem = 0;
|
||||
if (!state->Call("collectgarbage", "count", cLuaState::Return, Mem))
|
||||
{
|
||||
res.append(Printf("Cannot query memory for state \"%s\"\n", state->GetSubsystemName().c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
res.append(Printf("State \"%s\" is using %d KiB of memory\n", state->GetSubsystemName().c_str(), Mem));
|
||||
Total += Mem;
|
||||
}
|
||||
}
|
||||
res.append(Printf("Total memory used by Lua: %d KiB\n", Total));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cLuaStateTracker & cLuaStateTracker::Get(void)
|
||||
{
|
||||
static cLuaStateTracker Inst; // The singleton
|
||||
return Inst;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cLuaState:
|
||||
|
||||
@ -98,6 +168,7 @@ void cLuaState::Create(void)
|
||||
m_LuaState = lua_open();
|
||||
luaL_openlibs(m_LuaState);
|
||||
m_IsOwned = true;
|
||||
cLuaStateTracker::Add(*this);
|
||||
}
|
||||
|
||||
|
||||
@ -133,6 +204,7 @@ void cLuaState::Close(void)
|
||||
Detach();
|
||||
return;
|
||||
}
|
||||
cLuaStateTracker::Del(*this);
|
||||
lua_close(m_LuaState);
|
||||
m_LuaState = nullptr;
|
||||
m_IsOwned = false;
|
||||
|
@ -210,6 +210,9 @@ public:
|
||||
|
||||
/** Returns true if the m_LuaState is valid */
|
||||
bool IsValid(void) const { return (m_LuaState != nullptr); }
|
||||
|
||||
/** Returns the name of the subsystem, as specified when the instance was created. */
|
||||
AString GetSubsystemName(void) const { return m_SubsystemName; }
|
||||
|
||||
/** Adds the specified path to package.<a_PathVariable> */
|
||||
void AddPackagePath(const AString & a_PathVariable, const AString & a_Path);
|
||||
@ -521,3 +524,37 @@ protected:
|
||||
|
||||
|
||||
|
||||
|
||||
/** Keeps track of all create cLuaState instances.
|
||||
Can query each for the amount of currently used memory. */
|
||||
class cLuaStateTracker
|
||||
{
|
||||
public:
|
||||
/** Adds the specified Lua state to the internal list of LuaStates. */
|
||||
static void Add(cLuaState & a_LuaState);
|
||||
|
||||
/** Deletes the specified Lua state from the internal list of LuaStates. */
|
||||
static void Del(cLuaState & a_LuaState);
|
||||
|
||||
/** Returns the statistics for all the registered LuaStates. */
|
||||
static AString GetStats(void);
|
||||
|
||||
protected:
|
||||
typedef cLuaState * cLuaStatePtr;
|
||||
typedef std::vector<cLuaStatePtr> cLuaStatePtrs;
|
||||
|
||||
/** The internal list of LuaStates.
|
||||
Protected against multithreaded access by m_CSLuaStates. */
|
||||
cLuaStatePtrs m_LuaStates;
|
||||
|
||||
/** Protects m_LuaStates against multithreaded access. */
|
||||
cCriticalSection m_CSLuaStates;
|
||||
|
||||
|
||||
/** Returns the single instance of this class. */
|
||||
static cLuaStateTracker & Get(void);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -145,6 +145,8 @@ cServer::cServer(void) :
|
||||
m_ShouldLoadOfflinePlayerData(false),
|
||||
m_ShouldLoadNamedPlayerData(true)
|
||||
{
|
||||
// Initialize the LuaStateTracker singleton before the app goes multithreaded:
|
||||
cLuaStateTracker::GetStats();
|
||||
}
|
||||
|
||||
|
||||
@ -522,6 +524,13 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac
|
||||
a_Output.Finished();
|
||||
return;
|
||||
}
|
||||
|
||||
else if (split[0].compare("luastats") == 0)
|
||||
{
|
||||
a_Output.Out(cLuaStateTracker::GetStats());
|
||||
a_Output.Finished();
|
||||
return;
|
||||
}
|
||||
#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
|
||||
else if (split[0].compare("dumpmem") == 0)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user