How to know where memory is allocated for the reference and value type?

As I know if the int variable ( value type ) is declared directly within a class ( reference type ), the memory for the variable allocated on the heap .

But if there is a method in a class and the variable is declared inside a method, or is it an argument, the memory allocated on the stack .

public class A
{
    int x; // heap

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

How can I see, where memory is allocated?


When you say 'where memory is located', I assume you mean the actual virtual address given to the variable, and perhaps the committed block or region which it resides in private bytes. While this trivial at best since it may be moved around (which is why native interop developers must pin the memory prior to use), you could hunt down the variable locations similar to the following:

Given the source (and breakpoint):

资源

Allow disassembly (Option-->Debugging-->General-->Show disassembly...) Right-Click (Context Menu): Select 'Go To Disassembly'

Note the assignment of z:

mov dword ptr [ebp-44h],eax

Open the registers window (Debug-->Windows-->Registers). Note the value of EBP (base pointer) == 0x05C0EF18.

Use calc (programmer mode) to determine [ebp-44h] from above. 0x05C0EF18 - 0x44 == 0x05C0EED4

Take a peek at that memory location (Debug-->Windows-->Memory-->Memory 1) Paste in the result value (0x05C0EED4 for this instance).

Note the value

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

We can determine (for now) that z is located at 0x05C0EED4 and has 1234567 (decimal) stored in it's location.

A bit more complicated with x however. x is located at 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)

However, also interesting is the virtual memory map. Use vmmmap.exe from sysinternals to get a better picture of the reserved and committed pages. You can then poke around the different generations in the GC, etc.

虚拟内存

Hope this helps!

链接地址: http://www.djcxy.com/p/14074.html

上一篇: 内存分配给指针和它们的数据在哪里?

下一篇: 如何知道内存分配给引用和值类型?