#4298 Record memory in bugsplat's attributes (FS:TJ- Cherry-pick to try improve FIRE-36494)
# Conflicts: # indra/newview/llappviewerwin32.cppmaster
parent
fc6f4ee6a9
commit
fb4a8153f3
|
|
@ -52,6 +52,9 @@
|
|||
|
||||
//static
|
||||
|
||||
// On windows commit charge information is vital for OOM diagnosis.
|
||||
U32Megabytes LLMemory::sAvailCommitMemInMB(U32_MAX);
|
||||
|
||||
// most important memory metric for texture streaming
|
||||
// On Windows, this should agree with resource monitor -> performance -> memory -> available
|
||||
// On OS X, this should be activity monitor -> memory -> (physical memory - memory used)
|
||||
|
|
@ -104,21 +107,11 @@ void LLMemory::updateMemoryInfo()
|
|||
|
||||
sMaxPhysicalMemInKB = gSysMemory.getPhysicalMemoryKB();
|
||||
|
||||
U32Kilobytes avail_mem;
|
||||
LLMemoryInfo::getAvailableMemoryKB(avail_mem);
|
||||
sAvailPhysicalMemInKB = avail_mem;
|
||||
LLMemoryInfo::updateAvailableMemory();
|
||||
|
||||
#if LL_WINDOWS
|
||||
PROCESS_MEMORY_COUNTERS counters;
|
||||
|
||||
if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
|
||||
{
|
||||
LL_WARNS() << "GetProcessMemoryInfo failed" << LL_ENDL;
|
||||
return ;
|
||||
}
|
||||
|
||||
sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(counters.WorkingSetSize));
|
||||
sAllocatedPageSizeInKB = U32Kilobytes::convert(U64Bytes(counters.PagefileUsage));
|
||||
// On windows getAvailableMemoryKB fills sAvailPhysicalMemInKB,
|
||||
//sAllocatedMemInKB and sAllocatedPageSizeInKB
|
||||
sample(sVirtualMem, sAllocatedPageSizeInKB);
|
||||
|
||||
#elif defined(LL_DARWIN)
|
||||
|
|
@ -201,6 +194,17 @@ void LLMemory::logMemoryInfo(bool update)
|
|||
LL_INFOS() << llformat("Current max usable memory: %.2f MB", sMaxPhysicalMemInKB / 1024.0) << LL_ENDL;
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
//static
|
||||
U32Megabytes LLMemory::getAvailableCommitMemMB()
|
||||
{
|
||||
// Commit charge combines page file and ram,
|
||||
// theoretical limit is 128TB on 64bit windows.
|
||||
// Store as MB instead of KB to prevent overflow.
|
||||
return sAvailCommitMemInMB;
|
||||
}
|
||||
#endif
|
||||
|
||||
//static
|
||||
U32Kilobytes LLMemory::getAvailableMemKB()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -441,10 +441,18 @@ public:
|
|||
static void updateMemoryInfo() ;
|
||||
static void logMemoryInfo(bool update = false);
|
||||
|
||||
#if LL_WINDOWS
|
||||
// Commit charge is a Windows-only concept, combines page file and ram
|
||||
static U32Megabytes getAvailableCommitMemMB();
|
||||
#endif
|
||||
static U32Kilobytes getAvailableMemKB() ;
|
||||
static U32Kilobytes getMaxMemKB() ;
|
||||
static U32Kilobytes getAllocatedMemKB() ;
|
||||
private:
|
||||
// LLMemoryInfo directly updates memory stats
|
||||
friend class LLMemoryInfo;
|
||||
|
||||
static U32Megabytes sAvailCommitMemInMB;
|
||||
static U32Kilobytes sAvailPhysicalMemInKB ;
|
||||
static U32Kilobytes sMaxPhysicalMemInKB ;
|
||||
static U32Kilobytes sAllocatedMemInKB;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "llerrorcontrol.h"
|
||||
#include "llevents.h"
|
||||
#include "llformat.h"
|
||||
#include "llmemory.h"
|
||||
#include "llregex.h"
|
||||
#include "lltimer.h"
|
||||
#include "llsdserialize.h"
|
||||
|
|
@ -809,16 +810,13 @@ U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
|
|||
}
|
||||
|
||||
//static
|
||||
void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb)
|
||||
void LLMemoryInfo::updateAvailableMemory()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
|
||||
#if LL_WINDOWS
|
||||
// Sigh, this shouldn't be a static method, then we wouldn't have to
|
||||
// reload this data separately from refresh()
|
||||
|
||||
LLSD statsMap(loadStatsMap());
|
||||
|
||||
avail_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger();
|
||||
// On windows loadStatsMap will fill sAvailPhysicalMemInKB,
|
||||
// sAvailCommitMemInMB, sAllocatedMemInKB and sAllocatedPageSizeInKB
|
||||
loadStatsMap();
|
||||
|
||||
#elif LL_DARWIN
|
||||
// use host_statistics64 to get memory info
|
||||
|
|
@ -830,11 +828,11 @@ void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb)
|
|||
kern_return_t result = host_statistics64(host, HOST_VM_INFO64, reinterpret_cast<host_info_t>(&vmstat), &count);
|
||||
if (result == KERN_SUCCESS)
|
||||
{
|
||||
avail_mem_kb = U64Bytes((vmstat.free_count + vmstat.inactive_count) * page_size);
|
||||
LLMemory::sAvailPhysicalMemInKB = U64Bytes((vmstat.free_count + vmstat.inactive_count) * page_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
avail_mem_kb = (U32Kilobytes)-1;
|
||||
LLMemory::sAvailPhysicalMemInKB = (U32Kilobytes)-1;
|
||||
}
|
||||
|
||||
#elif LL_LINUX
|
||||
|
|
@ -888,12 +886,12 @@ void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb)
|
|||
// (could also run 'free', but easier to read a file than run a program)
|
||||
LLSD statsMap(loadStatsMap());
|
||||
|
||||
avail_mem_kb = (U32Kilobytes)statsMap["MemFree"].asInteger();
|
||||
LLMemory::sAvailPhysicalMemInKB = (U32Kilobytes)statsMap["MemFree"].asInteger();
|
||||
#else
|
||||
//do not know how to collect available memory info for other systems.
|
||||
//leave it blank here for now.
|
||||
|
||||
avail_mem_kb = (U32Kilobytes)-1 ;
|
||||
LLMemory::sAvailPhysicalMemInKB = (U32Kilobytes)-1 ;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -966,26 +964,35 @@ LLSD LLMemoryInfo::loadStatsMap()
|
|||
|
||||
static constexpr DWORDLONG div = 1024;
|
||||
|
||||
stats.add("Percent Memory use", state.dwMemoryLoad/div);
|
||||
stats.add("Percent Memory use", state.dwMemoryLoad);
|
||||
// <FS:Ansariel> Ugly, but prevent overflow
|
||||
//stats.add("Total Physical KB", state.ullTotalPhys/div);
|
||||
//stats.add("Avail Physical KB", state.ullAvailPhys/div);
|
||||
stats.add("Total Physical KB", llclamp(state.ullTotalPhys / div, U64(0), U64(S32_MAX)));
|
||||
stats.add("Avail Physical KB", llclamp(state.ullAvailPhys / div, U64(0), U64(S32_MAX)));
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Despite the confusing naming "PageFile" , these values
|
||||
// actually represent the committed memory limit for
|
||||
// the system or the current process, whichever is smaller.
|
||||
// <FS:Ansariel> Ugly, but prevent overflow
|
||||
//stats.add("Total page KB", state.ullTotalPageFile/div);
|
||||
//stats.add("Avail page KB", state.ullAvailPageFile/div);
|
||||
|
||||
//static constexpr DWORDLONG mb_div = 1024 * 1024;
|
||||
//stats.add("Total Virtual MB", state.ullTotalVirtual/mb_div); // ~134 million MB
|
||||
//stats.add("Avail Virtual MB", state.ullAvailVirtual/mb_div);
|
||||
stats.add("Total Physical KB", llclamp(state.ullTotalPhys/div, U64(0), U64(S32_MAX)));
|
||||
stats.add("Avail Physical KB", llclamp(state.ullAvailPhys/div, U64(0), U64(S32_MAX)));
|
||||
stats.add("Total page KB", llclamp(state.ullTotalPageFile/div, U64(0), U64(S32_MAX)));
|
||||
stats.add("Avail page KB", llclamp(state.ullAvailPageFile/div, U64(0), U64(S32_MAX)));
|
||||
stats.add("Total page KB", llclamp(state.ullTotalPageFile / div, U64(0), U64(S32_MAX)));
|
||||
stats.add("Avail page KB", llclamp(state.ullAvailPageFile / div, U64(0), U64(S32_MAX)));
|
||||
|
||||
static constexpr DWORDLONG mb_div = 1024 * 1024;
|
||||
stats.add("Total Virtual MB", llclamp(state.ullTotalVirtual / mb_div, U64(0), U64(S32_MAX)));
|
||||
stats.add("Avail Virtual MB", llclamp(state.ullAvailVirtual / mb_div, U64(0), U64(S32_MAX)));
|
||||
// </FS:Ansariel>
|
||||
|
||||
LLMemory::sAvailPhysicalMemInKB = U32Kilobytes::convert(U64Bytes(state.ullAvailPhys));
|
||||
LLMemory::sAvailCommitMemInMB = U32Megabytes::convert(U64Bytes(state.ullAvailPageFile));
|
||||
|
||||
// SL-12122 - Call to GetPerformanceInfo() was removed here. Took
|
||||
// on order of 10 ms, causing unacceptable frame time spike every
|
||||
// second, and results were never used. If this is needed in the
|
||||
|
|
@ -1000,18 +1007,38 @@ LLSD LLMemoryInfo::loadStatsMap()
|
|||
// specifically accepts PROCESS_MEMORY_COUNTERS*, and since this is a
|
||||
// classic-C API, PROCESS_MEMORY_COUNTERS_EX isn't a subclass. Cast the
|
||||
// pointer.
|
||||
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmem, sizeof(pmem));
|
||||
if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmem, sizeof(pmem)))
|
||||
{
|
||||
LLMemory::sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(pmem.WorkingSetSize));
|
||||
LLMemory::sAllocatedPageSizeInKB = U32Kilobytes::convert(U64Bytes(pmem.PagefileUsage));
|
||||
|
||||
stats.add("Page Fault Count", pmem.PageFaultCount);
|
||||
stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize/div);
|
||||
stats.add("WorkingSetSize KB", pmem.WorkingSetSize/div);
|
||||
stats.add("QutaPeakPagedPoolUsage KB", pmem.QuotaPeakPagedPoolUsage/div);
|
||||
stats.add("QuotaPagedPoolUsage KB", pmem.QuotaPagedPoolUsage/div);
|
||||
stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage/div);
|
||||
stats.add("QuotaNonPagedPoolUsage KB", pmem.QuotaNonPagedPoolUsage/div);
|
||||
stats.add("PagefileUsage KB", pmem.PagefileUsage/div);
|
||||
stats.add("PeakPagefileUsage KB", pmem.PeakPagefileUsage/div);
|
||||
stats.add("PrivateUsage KB", pmem.PrivateUsage/div);
|
||||
stats.add("Page Fault Count", pmem.PageFaultCount);
|
||||
stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize / div);
|
||||
stats.add("WorkingSetSize KB", pmem.WorkingSetSize / div);
|
||||
stats.add("QuotaPeakPagedPoolUsage KB", pmem.QuotaPeakPagedPoolUsage / div);
|
||||
stats.add("QuotaPagedPoolUsage KB", pmem.QuotaPagedPoolUsage / div);
|
||||
stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage / div);
|
||||
stats.add("QuotaNonPagedPoolUsage KB", pmem.QuotaNonPagedPoolUsage / div);
|
||||
stats.add("PagefileUsage KB", pmem.PagefileUsage / div);
|
||||
stats.add("PeakPagefileUsage KB", pmem.PeakPagefileUsage / div);
|
||||
stats.add("PrivateUsage KB", pmem.PrivateUsage / div);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLMemory::sAllocatedMemInKB = U32Kilobytes(0);
|
||||
LLMemory::sAllocatedPageSizeInKB = U32Kilobytes(0);
|
||||
|
||||
stats.add("Page Fault Count", 0);
|
||||
stats.add("PeakWorkingSetSize KB", 0);
|
||||
stats.add("WorkingSetSize KB", 0);
|
||||
stats.add("QuotaPeakPagedPoolUsage KB", 0);
|
||||
stats.add("QuotaPagedPoolUsage KB", 0);
|
||||
stats.add("QuotaPeakNonPagedPoolUsage KB", 0);
|
||||
stats.add("QuotaNonPagedPoolUsage KB", 0);
|
||||
stats.add("PagefileUsage KB", 0);
|
||||
stats.add("PeakPagefileUsage KB", 0);
|
||||
stats.add("PrivateUsage KB", 0);
|
||||
}
|
||||
|
||||
#elif LL_DARWIN
|
||||
|
||||
|
|
|
|||
|
|
@ -134,11 +134,12 @@ public:
|
|||
static U32Kilobytes getHardwareMemSize(); // Because some Mac linkers won't let us reference extern gSysMemory from a different lib.
|
||||
#endif
|
||||
|
||||
//get the available memory in KiloBytes.
|
||||
static void getAvailableMemoryKB(U32Kilobytes& avail_mem_kb);
|
||||
// Updates LLMemory's values (which ones is OS specific).
|
||||
static void updateAvailableMemory();
|
||||
|
||||
// Retrieve a map of memory statistics. The keys of the map are platform-
|
||||
// dependent. The values are in kilobytes to try to avoid integer overflow.
|
||||
// On windows updates LLMemory values.
|
||||
LLSD getStatsMap() const;
|
||||
|
||||
// Re-fetch memory data (as reported by stream() and getStatsMap()) from the
|
||||
|
|
|
|||
|
|
@ -234,6 +234,12 @@ namespace
|
|||
BugSplatAttributes::instance().setAttribute("AppState", LLStartUp::getStartupStateString());
|
||||
// Location
|
||||
// </FS:Beq>
|
||||
// Memory usage at crash time (can be 1s obsolete)
|
||||
sBugSplatSender->setAttribute(WCSTR(L"MemAllocatedKB"), WCSTR(std::to_string(LLMemory::getAllocatedMemKB().value())));
|
||||
sBugSplatSender->setAttribute(WCSTR(L"MemAvailableKB"), WCSTR(std::to_string(LLMemory::getAvailableMemKB().value())));
|
||||
sBugSplatSender->setAttribute(WCSTR(L"MemMaxPhysicalKB"), WCSTR(std::to_string(LLMemory::getMaxMemKB().value())));
|
||||
sBugSplatSender->setAttribute(WCSTR(L"MemAvailCommitMB"), WCSTR(std::to_string(LLMemory::getAvailableCommitMemMB().value())));
|
||||
|
||||
if (gAgent.getRegion())
|
||||
{
|
||||
// region location, when we have it
|
||||
|
|
|
|||
Loading…
Reference in New Issue