動態

詳情 返回 返回

結合生活中的場景來理解棧內存跟堆內存的區別 - 動態 詳情

在程序開發中經常遇到值類型的數據跟引用類型的數據, 值類型的數據存儲在棧內存中, 引用類型的數據實例存儲在堆內存中, 變量保存的時候對象在堆內存中的引用地址.

棧內存跟堆內存兩者有啥區別哪?

我們可以用生活中常見的"快遞收發"場景來對比兩者的區別.
先建立一個核心比喻:內存 = 快遞站點
把整個計算機內存想象成一個 “快遞站點”,站點裏有兩種存放快遞的區域:

  • 棧內存 = 站點前台的 “臨時貨架”
  • 堆內存 = 站點後院的"長期倉庫"

    棧內存(臨時貨架): 快、小、自動收拾

    棧內存就像前台的小貨架,特點是 “即拿即用、用完就扔”,完全不用你操心收拾:

  • 存取速度快:貨架就在前台,取快遞、放快遞一步到位,比去後院倉庫快得多。
  • 空間小且固定:貨架層數有限(對應棧內存的固定大小),只能放小包裹(簡單數據,比如數字、bool 值,或 struct 的完整數據)。
  • 自動回收:你取走快遞後,貨架會自動清空這個位置(函數執行完,棧內存裏的數據會被自動銷燬),不用手動整理。
    比如你定義一個普通 struct(值類型):

    // 普通struct(值類型)= 小包裹
    struct Point { x: number; y: number }
    const p = new Point(); // 實例化 = 把小包裹放前台貨架
    p.x = 10; p.y = 20;
    

    這時 p 的完整數據(x=10、y=20)就像一個小包裹,直接放在棧內存的 “臨時貨架” 上,你用的時候直接從貨架拿,用完自動清走。

堆內存(長期倉庫): 大、靈活、需標記收拾

堆內存像後院的大倉庫,特點是 “能放大傢伙、但得記位置”:

  • 存取速度慢:倉庫在後台,放快遞、取快遞都要先找倉庫管理員登記位置,比前台貨架慢。
  • 空間大且靈活:倉庫能放超大包裹(複雜數據,比如 class 實例的完整數據),空間不夠時還能臨時擴容。
  • 手動 / 自動回收:包裹放進去後,不會自動消失,需要你記清 “倉庫編號”(引用地址)才能找到;如果忘了編號,包裹就成了 “垃圾”,得等 “清潔工”(垃圾回收器)定期清理。
    比如你定義一個 class(引用類型):

    // class(引用類型)= 大包裹
    class User { name: string; age: number }
    const u = new User(); // 實例化 = 把大包裹放後院倉庫
    u.name = "張三"; u.age = 20;
    

    這時 u 這個變量,其實只是一張 “倉庫提貨單”—— 上面只寫了大包裹在堆內存的 “倉庫編號”(引用地址),而 “張三、20” 這些完整數據,都實實在在存在後院倉庫裏。你用 u.name 時,其實是拿着提貨單去倉庫找對應的包裹。

關鍵區別: 值類型 VS 引用類型的"複製"差異

這兩種存儲方式最直觀的區別,體現在 “複製數據” 的時候 —— 就像複製快遞的不同操作:

值類型(struct) 複製: 複製整個包裹

比如把 p1 複製給 p2:

const p1 = new Point(); p1.x=10; p1.y=20;
const p2 = p1; // 複製 = 把p1的小包裹完整複印一份,放前台另一個貨架
p2.x = 30; // 修改p2 = 改自己的複印包裹,和p1沒關係
console.log(p1.x); // 輸出10(p1的包裹沒動)

因為 struct 存在棧內存,複製時是 “完整拷貝”,兩個變量各自有獨立的包裹,改一個不影響另一個。

引用類型(class)複製: 複製提貨單

比如把 u1 複製給 u2:

const u1 = new User(); u1.name="張三";
const u2 = u1; // 複製 = 把u1的提貨單複印一份,兩張單指向同一個倉庫包裹
u2.name = "李四"; // 修改u2 = 拿着複印的提貨單,去倉庫改同一個包裹
console.log(u1.name); // 輸出李四(u1的包裹也被改了)

因為 class 存在堆內存,複製時只複製 “提貨單”(引用地址),兩個變量指向同一個倉庫包裹,改一個就會影響另一個。

總結

  • 棧內存 + 值類型(struct):像前台小貨架上的小包裹,拿取快、自動清、複製是完整複印,彼此獨立。
  • 堆內存 + 引用類型(class):像後院倉庫裏的大包裹,拿取慢、需記位置、複製是複印提貨單,共享同一個包裹。
user avatar hsr2022 頭像 gaungfa3 頭像 menglihuaxiangbian 頭像 tong_6816038415d24 頭像
點贊 4 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.