学习几个“××在内存中占几份”的若干问题
- 先需要明白一個問題:
COW:寫時復制,即:Copy-on-Write,當寫入時,進行拷貝:
無寫入操作:共用一份內存
有寫入操作:拷貝該塊出來供修改,并改變進程的內存地址映射,使之映射到到新的內存塊地址
這是一種內存優化策略,因為,當同一個EXE,或者同一個DLL執行的時候,程序段自然都是相同的;而在調用函數的時候壓入棧的數據段,有可能也是相同的,假如確實是相同的,則操作系統會將不同的進程的相同內存塊的部分映射到同一地址,其實,程序的執行無論代碼或者數據,都是基于地址的,操作系統則可以通過合理的管理這些地址,進行內存空間的優化。還有另一種情況是,假如數據段被某個或者某些進程修改了怎么辦呢?此時,會根據COW原則,對有修改操作的進程,將它們對該內存的控制權取消,轉移到另一塊內存去進行操作,避免造成共享內存數據的不一致性。關于全局函數和靜態變量,他們在下面這個問題上是等價的:就是只能在一個進程內部共享,而不會和另一個進程共享,因此,不同進程對于同一個DLL中全局或者靜態變量的修改,會導致系統給它專門分配一塊新的空間出來。
- 那么就有一個問題了:
如何通過一個DLL去實現進程間的數據共享呢?
有一種聲明,導出,載入共享數據段的方式,但是似乎這種方法并不可行,或者說,最起碼,不被推崇。
而最受歡迎的是mmap/munmap方法,多個進程,將同一個文件,映射到內存,此時,他們能(宏觀上)同時對該內存進行讀寫操作,進而完成數據共享。
- 虛函數,靜態函數,成員函數:是否放在代碼區同等的位置:
是的,都放在類作用域內(區別于對象的作用域:對象的作用域是指對象所占的堆棧空間);類的作用域空間無非是該類的常量空間,靜態變量空間,代碼空間(唯獨沒有堆棧等數據空間)。
由此也可知一個問題:內存分為堆、棧、代碼、靜態、常量,共五類空間。
- static函數的問題:
另一個問題:類中static函數的問題:非static函數都會使用__thiscall方法調用,該方法實質會傳入this指針作為參數,將函數中的變量重新映射到實例對應的數據區,從而對實例的成員變量進行訪問;然而,static方法不會傳入this指針,因此他無法訪問成員函數,虛函數必須能訪問虛函數表,這個表指針是存放在實例空間中的,因此虛函數不能是static方法,否則無法訪問虛函數表。
- 虛函數表具體存放在什么位置:
存放在類作用域的常量區。
- 那些數據是放在類作用域的內存空間,那些數據是放在對象的內存空間:
成員函數代碼,靜態函數代碼,虛函數代碼,靜態變量,常量,虛函數表:存放在類定義區;
虛函數表指針,成員變量:放在對象實例區。
做個實驗:
修改兩個不同類的“虛函數表指針”,看看是否如期望的那樣:對象初始的4個字節存放“虛函數表”
代碼:
1 #include <stdlib.h> 2 3 /*** 4 * @author:zanzan101 5 */ 6 7 class A 8 { 9 private: 10 int data; 11 public: 12 virtual int foo() 13 { 14 printf("A\n"); 15 return 1; 16 } 17 }; 18 19 class B : public A 20 { 21 public: 22 int foo() 23 { 24 printf("B\n"); 25 return 2; 26 } 27 }; 28 29 class C : public A 30 { 31 public: 32 int foo() 33 { 34 printf("C\n"); 35 return 3; 36 } 37 }; 38 39 void func(const char* str) 40 { 41 printf("%s\n", str); 42 } 43 44 typedef void (*ptr_of_func)(const char *); // 這是個類型定義 45 ptr_of_func p = func; // 這是個變量聲明及初始化 46 47 // 分開操作則報錯 48 // ptr_of_func q; 49 // q = func; 50 51 int main() 52 { 53 C c; 54 B b; 55 A* ptr = &b; 56 if(2 == ptr->foo()) 57 p("多態:調用了B的函數!"); 58 59 // 修改B的對象的前4個字節的數據為C對象的前4個字節的數據 60 p("修改B的對象的前4個字節的數據為C對象的前4個字節的數據"); 61 memcpy(&b, &c, sizeof(void*)); 62 63 if(3 == ptr->foo()) 64 p("虛函數表指針被修改了!"); 65 66 system("pause"); 67 return 0; 68 }輸出:
B 多態:調用了B的函數! 修改B的對象的前4個字節的數據為C對象的前4個字節的數據 C 虛函數表指針被修改了! 請按任意鍵繼續. . .?
>>轉載請注明出處<<
轉載于:https://www.cnblogs.com/zanzan101/p/3383462.html
總結
以上是生活随笔為你收集整理的学习几个“××在内存中占几份”的若干问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx+Firebug 让浏览器告诉
- 下一篇: View Horizon Mirage安