summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2024-07-09 15:54:18 -0500
committerGitHub <noreply@github.com>2024-07-09 15:54:18 -0500
commite6e41e71b7bc860faee8cd13c56f7180e8eb4745 (patch)
tree57921be1de663dbcf0dd1ff1fb10aa1dd4c4dda7 /indra/llcommon
parent21f40280eca12bca53e9894f01cac2e205bb2827 (diff)
#1943 make sys free in texture console llmemorysavailphysicalmeminkb tell the truth (#1966)
* Also fix for crash when applying MoaP to PBR material
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llmemory.cpp74
-rw-r--r--indra/llcommon/llsys.cpp49
-rw-r--r--indra/llcommon/llsys.h5
3 files changed, 60 insertions, 68 deletions
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 104c40f0d7..81e8073dbf 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -51,13 +51,28 @@
//----------------------------------------------------------------------------
//static
+
+// 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)
+// NOTE: this number MAY be less than the actual available memory on systems with more than MaxHeapSize64 GB of physical memory (default 16GB)
+// In that case, should report min(available, sMaxHeapSizeInKB-sAllocateMemInKB)
U32Kilobytes LLMemory::sAvailPhysicalMemInKB(U32_MAX);
+
+// Installed physical memory
U32Kilobytes LLMemory::sMaxPhysicalMemInKB(0);
-static LLTrace::SampleStatHandle<F64Megabytes> sAllocatedMem("allocated_mem", "active memory in use by application");
-static LLTrace::SampleStatHandle<F64Megabytes> sVirtualMem("virtual_mem", "virtual memory assigned to application");
+
+// Maximimum heap size according to the user's settings (default 16GB)
+U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
+
+// Current memory usage
U32Kilobytes LLMemory::sAllocatedMemInKB(0);
+
U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0);
-U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
+
+
+static LLTrace::SampleStatHandle<F64Megabytes> sAllocatedMem("allocated_mem", "active memory in use by application");
+static LLTrace::SampleStatHandle<F64Megabytes> sVirtualMem("virtual_mem", "virtual memory assigned to application");
void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
{
@@ -86,7 +101,14 @@ void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size)
void LLMemory::updateMemoryInfo()
{
LL_PROFILE_ZONE_SCOPED
- U32Kilobytes avail_phys;
+
+
+ sMaxPhysicalMemInKB = gSysMemory.getPhysicalMemoryKB();
+
+ U32Kilobytes avail_mem;
+ LLMemoryInfo::getAvailableMemoryKB(avail_mem);
+ sAvailPhysicalMemInKB = avail_mem;
+
#if LL_WINDOWS
PROCESS_MEMORY_COUNTERS counters;
@@ -99,8 +121,6 @@ void LLMemory::updateMemoryInfo()
sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(counters.WorkingSetSize));
sAllocatedPageSizeInKB = U32Kilobytes::convert(U64Bytes(counters.PagefileUsage));
sample(sVirtualMem, sAllocatedPageSizeInKB);
- U32Kilobytes avail_virtual;
- LLMemoryInfo::getAvailableMemoryKB(avail_phys, avail_virtual) ;
#elif defined(LL_DARWIN)
task_vm_info info;
@@ -126,50 +146,20 @@ void LLMemory::updateMemoryInfo()
{
LL_WARNS() << "task_info failed" << LL_ENDL;
}
-
- // Total installed and available physical memory are properties of the host, not just our process.
- vm_statistics64_data_t vmstat;
- mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
- mach_port_t host = mach_host_self();
- vm_size_t page_size;
- host_page_size(host, &page_size);
- kern_return_t result = host_statistics64(host, HOST_VM_INFO64, reinterpret_cast<host_info_t>(&vmstat), &count);
- if (result == KERN_SUCCESS) {
- // This is what Chrome reports as 'the "Physical Memory Free" value reported by the Memory Monitor in Instruments.'
- // Note though that inactive pages are not included here and not yet free, but could become so under memory pressure.
- avail_phys = U32Bytes(vmstat.free_count * page_size);
- sMaxHeapSizeInKB = LLMemoryInfo::getHardwareMemSize();
- }
- else
- {
- LL_WARNS() << "task_info failed" << LL_ENDL;
- }
#elif defined(LL_LINUX)
// Use sysinfo() to get the total physical memory.
struct sysinfo info;
sysinfo(&info);
- sMaxHeapSizeInKB = U32Kilobytes::convert((U64Bytes)info.totalram); // Total RAM in system
- avail_phys = U32Kilobytes::convert((U64Bytes)info.freeram); // Total Free RAM in system
sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(LLMemory::getCurrentRSS())); // represents the RAM allocated by this process only (in line with the windows implementation)
#else
//not valid for other systems for now.
LL_WARNS() << "LLMemory::updateMemoryInfo() not implemented for this platform." << LL_ENDL;
sAllocatedMemInKB = U64Bytes(LLMemory::getCurrentRSS());
- sMaxPhysicalMemInKB = U64Bytes(U32_MAX);
- sAvailPhysicalMemInKB = U64Bytes(U32_MAX);
#endif
sample(sAllocatedMem, sAllocatedMemInKB);
- // sMaxPhysicalMem - max this process can use = the lesser of (what we already have + what's available) or MaxHeap
- sMaxPhysicalMemInKB = llmin(avail_phys + sAllocatedMemInKB, sMaxHeapSizeInKB);
- if(sMaxPhysicalMemInKB > sAllocatedMemInKB)
- {
- sAvailPhysicalMemInKB = sMaxPhysicalMemInKB - sAllocatedMemInKB ;
- }
- else
- {
- sAvailPhysicalMemInKB = U32Kilobytes(0);
- }
+ sAvailPhysicalMemInKB = llmin(sAvailPhysicalMemInKB, sMaxHeapSizeInKB - sAllocatedMemInKB);
+
return ;
}
@@ -206,10 +196,10 @@ void LLMemory::logMemoryInfo(bool update)
updateMemoryInfo() ;
}
- LL_INFOS() << "Current allocated physical memory(KB): " << sAllocatedMemInKB << LL_ENDL ;
- LL_INFOS() << "Current allocated page size (KB): " << sAllocatedPageSizeInKB << LL_ENDL ;
- LL_INFOS() << "Current available physical memory(KB): " << sAvailPhysicalMemInKB << LL_ENDL ;
- LL_INFOS() << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << LL_ENDL ;
+ LL_INFOS() << llformat("Current allocated physical memory: %.2f MB", sAllocatedMemInKB / 1024.0) << LL_ENDL;
+ LL_INFOS() << llformat("Current allocated page size: %.2f MB", sAllocatedPageSizeInKB / 1024.0) << LL_ENDL;
+ LL_INFOS() << llformat("Current available physical memory: %.2f MB", sAvailPhysicalMemInKB / 1024.0) << LL_ENDL;
+ LL_INFOS() << llformat("Current max usable memory: %.2f MB", sMaxPhysicalMemInKB / 1024.0) << LL_ENDL;
}
//static
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index cfb05873df..8bee33be0a 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -74,6 +74,8 @@ using namespace llsd;
# include <mach/mach_host.h>
# include <mach/task.h>
# include <mach/task_info.h>
+# include <sys/types.h>
+# include <mach/mach_init.h>
#elif LL_LINUX
# include <errno.h>
# include <sys/utsname.h>
@@ -85,6 +87,7 @@ const char MEMINFO_FILE[] = "/proc/meminfo";
#endif
LLCPUInfo gSysCPU;
+LLMemoryInfo gSysMemory;
// Don't log memory info any more often than this. It also serves as our
// framerate sample size.
@@ -797,33 +800,32 @@ U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
}
//static
-void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb)
+void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb)
{
+ 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_physical_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger();
- avail_virtual_mem_kb = (U32Kilobytes)statsMap["Avail Virtual KB"].asInteger();
+ avail_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger();
#elif LL_DARWIN
- // mStatsMap is derived from vm_stat, look for (e.g.) "kb free":
- // $ vm_stat
- // Mach Virtual Memory Statistics: (page size of 4096 bytes)
- // Pages free: 462078.
- // Pages active: 142010.
- // Pages inactive: 220007.
- // Pages wired down: 159552.
- // "Translation faults": 220825184.
- // Pages copy-on-write: 2104153.
- // Pages zero filled: 167034876.
- // Pages reactivated: 65153.
- // Pageins: 2097212.
- // Pageouts: 41759.
- // Object cache: 841598 hits of 7629869 lookups (11% hit rate)
- avail_physical_mem_kb = (U32Kilobytes)-1 ;
- avail_virtual_mem_kb = (U32Kilobytes)-1 ;
+ // use host_statistics64 to get memory info
+ vm_statistics64_data_t vmstat;
+ mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
+ mach_port_t host = mach_host_self();
+ vm_size_t page_size;
+ host_page_size(host, &page_size);
+ 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);
+ }
+ else
+ {
+ avail_mem_kb = (U32Kilobytes)-1;
+ }
#elif LL_LINUX
// mStatsMap is derived from MEMINFO_FILE:
@@ -874,15 +876,14 @@ void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32
// DirectMap4k: 434168 kB
// DirectMap2M: 477184 kB
// (could also run 'free', but easier to read a file than run a program)
- avail_physical_mem_kb = (U32Kilobytes)-1 ;
- avail_virtual_mem_kb = (U32Kilobytes)-1 ;
+ LLSD statsMap(loadStatsMap());
+ avail_mem_kb = (U32Kilobytes)statsMap["MemFree"].asInteger();
#else
//do not know how to collect available memory info for other systems.
//leave it blank here for now.
- avail_physical_mem_kb = (U32Kilobytes)-1 ;
- avail_virtual_mem_kb = (U32Kilobytes)-1 ;
+ avail_mem_kb = (U32Kilobytes)-1 ;
#endif
}
@@ -977,7 +978,7 @@ 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(), PPROCESS_MEMORY_COUNTERS(&pmem), sizeof(pmem));
+ GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmem, sizeof(pmem));
stats.add("Page Fault Count", pmem.PageFaultCount);
stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize/div);
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index f97d49eeb1..827b0dc048 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -134,8 +134,8 @@ public:
static U32Kilobytes getHardwareMemSize(); // Because some Mac linkers won't let us reference extern gSysMemory from a different lib.
#endif
- //get the available memory infomation in KiloBytes.
- static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb);
+ //get the available memory in KiloBytes.
+ static void getAvailableMemoryKB(U32Kilobytes& avail_mem_kb);
// 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.
@@ -169,6 +169,7 @@ bool LL_COMMON_API gunzip_file(const std::string& srcfile, const std::string& ds
// gzip srcfile into dstfile. Returns false on error.
bool LL_COMMON_API gzip_file(const std::string& srcfile, const std::string& dstfile);
+extern LL_COMMON_API LLMemoryInfo gSysMemory;
extern LL_COMMON_API LLCPUInfo gSysCPU;
#endif // LL_LLSYS_H