我正在开发一个应用程序,目前已经创建了成百上千个对象。
是否有可能确定(或者近似估计)对象(类实例)所分配的内存?
我正在开发一个应用程序,目前已经创建了成百上千个对象。
是否有可能确定(或者近似估计)对象(类实例)所分配的内存?
// Measure starting point memory use
GC_MemoryStart = System.GC.GetTotalMemory(true);
// Allocate a new byte array of 20000 elements (about 20000 bytes)
MyByteArray = new byte[20000];
// Obtain measurements after creating the new byte[]
GC_MemoryEnd = System.GC.GetTotalMemory(true);
// Ensure that the Array stays in memory and doesn't get optimized away
GC.KeepAlive(MyByteArray);
long Process_MemoryStart = 0;
Process MyProcess = System.Diagnostics.Process.GetCurrentProcess();
Process_MemoryStart = MyProcess.PrivateMemorySize64;
编辑: 我添加以下内容以澄清Charles Bretana提供的答案中的一些信息:
顺便说一下,CLR使用大约8个不同的堆:
希望对您有所帮助
要了解应用程序中的内存分配情况,可以在WinDbg中使用以下sos命令。
!dumpheap -stat
Dim myObjectSize As Long
Dim ms As New IO.MemoryStream
Dim bf As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
bf.Serialize(ms, myObject)
myObjectSize = ms.Position
这里有一个学术问题:对象在运行时的大小是多少? 这很有趣,但只有连接到正在运行的进程的性能分析器才能正确回答。我最近花了很长时间研究这个问题,并确定没有通用方法既准确又快速,以至于您永远不想在生产系统中使用它。像数字类型数组之类的简单情况有简单的答案,但除此之外,最好的答案是不要费心去计算。为什么你想知道这个?是否有其他可用的信息可以达到相同的目的?
在我的情况下,我最终想回答这个问题,是因为我有各种有用的数据,但可以丢弃以释放RAM以供更重要的服务使用。这里的代表是撤销堆栈和缓存。
最终,我得出结论,管理撤销堆栈和缓存大小的正确方法是查询可用内存量(它是64位进程,因此可以安全地假定所有内存都可用),然后允许添加更多项目,如果有足够大的RAM缓冲区,则要求删除项目,如果RAM不足。
对于任何正在寻找答案的Unity开发人员,这里有一种比较两个不同类内存分配的方法,灵感来自@varun的回答:
void Start()
{
var totalMemory = System.GC.GetTotalMemory(false);
var class1 = new Class1[100000];
System.GC.KeepAlive(class1);
for (int i = 0; i < 100000; i++)
{
class1[i] = new Class1();
}
var newTotalMemory = System.GC.GetTotalMemory(false);
Debug.Log($"Class1: {newTotalMemory} - {totalMemory} = {newTotalMemory - totalMemory}");
var class2 = new Class2[100000];
System.GC.KeepAlive(class2);
for (int i = 0; i < 100000; i++)
{
class2[i] = new Class2(10, 10);
}
var newTotalMemory2 = System.GC.GetTotalMemory(false);
Debug.Log($"Class2: {newTotalMemory2} - {newTotalMemory} = {newTotalMemory2 - newTotalMemory}");
}