【问题标题】:How to know where memory is allocated for the reference and value type?如何知道为引用和值类型分配的内存在哪里?
【发布时间】:2014-06-01 20:52:17
【问题描述】:

据我所知,int 变量(值类型)是否直接在引用类型),在上分配的变量的内存。

但是如果一个类中有一个方法并且变量是在一个方法中声明的,或者是一个参数,那么分配在stack上的内存。

public class A
{
    int x; // heap

    public void Func(int y) // stack
    {
        int z;  // stack
    }
}

如何查看内存分配的位置?

【问题讨论】:

  • 请看这个reference link,它是关于在asp.net框架中通过垃圾收集完成的内存管理。

标签: c# memory memory-management


【解决方案1】:

当您说“内存所在的位置”时, 我假设您的意思是赋予变量的实际虚拟地址, 也许还有它驻留在私有字节中的已提交块或区域。 虽然这充其量是微不足道的,因为它可能会被移动 (这就是为什么原生互操作开发人员必须在使用前固定内存), 您可以搜索类似于以下内容的变量位置:

给定源(和断点):

允许反汇编(选项-->调试-->常规-->显示反汇编...) 右键单击(上下文菜单):选择“转到反汇编”

注意z的赋值:

mov dword ptr [ebp-44h],eax

打开寄存器窗口(Debug-->Windows-->Registers)。 注意 EBP(基指针)的值 == 0x05C0EF18。

使用 calc(程序员模式)从上面确定 [ebp-44h]。 0x05C0EF18 - 0x44 == 0x05C0EED4

看看那个内存位置(Debug-->Windows-->Memory-->Memory 1) 粘贴结果值(此实例为 0x05C0EED4)。

注意值

 87 d6 12 00 // <-- Little Endian  (00 12 d6 87 <-- Big Endian)
             //     0x0012D687 (hex) == 1234567 (decimal)

我们可以确定(目前)z 位于 0x05C0EED4 并在其位置存储了 1234567(十进制)。

不过,x 有点复杂。 x 位于 EAX+4。

// Similar exercise as above... 
// values get moved into registers, then the assignment...
mov eax,dword ptr [ebp-3Ch]  // [ebp-3Ch] == 0x05C0EF18 - 0x3C == 0x05C0EEDC 
                             // Move the value at 0x05C0EEDC (7c d4 40 02) to EAX
                             // [7c d4 40 02] (Big Endian) --> [02 40 d4 7c] (Little Endian)
                             // [02 40 d4 7c] (Little Endian) == 0x0240d47c or 37803132 (decimal)

mov edx,dword ptr [ebp-40h]  // [ebp-40h] == 0x05C0EF18 - 0x40 == 0x05C0EED8
                             // Move the value at 0x05C0EED8 (87 d6 12 00) to EDX
                             // [87 d6 12 00] (Big Endian) --> [00 12 d6 87] (Little Endian)
                             // [00 12 d6 87] (Little Endian) == 0x0012d687 or 1234567 (decimal)

mov dword ptr [eax+4],edx    // [EAX == 0x0240d47c] + 4 = 0x240D480
                             // Move the value at EDX (0x0012d687 or 1234567 (decimal)) to 
                             // EAX+4 (x variable located at 0x240D480)
                             //       (currently holds [b1 cb 74 00] (Big Endian)
                             //       which is equal to 7654321 (decimal)

不过,同样有趣的是虚拟内存映射。使用 sysinternals 中的 vmmmap.exe 可以更好地了解保留和提交的页面。然后,您可以在 GC 等中遍历不同的代。

希望这会有所帮助!

【讨论】:

  • 谢谢,这是一个很好的答案 =)
猜你喜欢
  • 2023-01-12
  • 2014-02-11
  • 2017-02-28
  • 2012-08-06
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多