xsubcwkfide64060014055.gif
, w8 J6 {! `) Z; d7 V8 ]
点击上方蓝色字体,关注我们
) K7 w4 i3 A3 G; A/ A9 }7 b: h
" V, }7 Q$ d1 r: G8 O& h1! [ k; H7 l3 n2 S% a, ]
为什么要分为堆和栈" O0 [3 m: X8 k% R# L
管理不同生命周期的数据
# {' \9 q" I6 m2 G' D5 I1 x栈:主要用于管理函数调用过程中的局部变量等。
m+ W% ?# e* b1 y
6 T# |9 |, R9 |. u% _+ @当函数被调用时,相关的数据被压入栈中,函数执行完毕后,这些数据就被弹出栈,释放内存。
! y9 a# C* C2 M7 S( H* ~3 q+ a6 J, J p
就像你去餐厅吃饭,服务员给你拿来一套餐具,等你吃完离开,服务员就会把餐具收走,为下一位顾客准备。
0 F+ K/ z Y( A2 \
" }& l, A- e- G; u; Z! a& ?; Z这样可以高效地管理那些生命周期与函数执行相关的短期数据。- p' C) }3 O0 M" |) `6 w L5 ^
+ x* C) ]$ G( y% u% D1 a$ @7 u堆:用于存放那些生命周期不确定的数据,比如动态分配的对象。
6 `3 b8 l8 ]& l& r; m3 z5 \* v) c) w1 ]2 K2 T9 k2 b
你可以把堆想象成一个巨大的仓库,你可以根据需要随时去租用一块空间来存放你的物品(数据),而且只要你不主动归还(释放内存),这块空间就一直为你所用。
! g6 s# t2 S* b1 c' p; V* r$ y' v* O, V. n
8 W- x4 K2 p0 i/ \3 ~1 K! x提高内存使用效率
. P! G1 k* Q9 E; O5 e4 r栈的内存分配和释放非常快速,因为它的操作方式简单,遵循 “后进先出” 的原则。# Y9 ]# r1 `- A! ]. f! Q8 ?, O) q+ _7 a
! z) C7 ]2 H. d& w4 i9 R
这就像是在自动售货机前排队买饮料,先来的人先买完离开,后面的人紧跟着上前,秩序井然,效率很高。
q# a E% P8 B+ l- O' H9 f
7 X% a& l' G# F2 Q$ E% E堆的灵活性则允许程序员在运行时根据实际需求动态地分配和释放内存大小。
+ ~! z: I$ [9 a+ U) G3 ]$ L O8 u- w7 ~! v; n! J4 Z% {
比如你在玩拼图游戏,一开始不知道需要多大的空间来摆放拼图碎片,但是随着游戏的进行,你可以根据实际情况从堆中申请合适大小的空间来放置碎片。( w% M# M" h9 G
+ p% o% w; F& k9 \3 w3 B支持不同的编程需求
8 z" L* D- H3 P9 i9 d栈适合存放那些在函数内部使用的临时数据,因为它的自动管理机制可以避免程序员忘记释放内存而导致的内存泄漏问题。& B) z' m* y7 B4 V9 P6 k: L
+ d/ m5 g, E0 {6 p, B/ W比如你在写一篇文章,草稿纸上的临时笔记在你完成文章后就可以自然地丢弃,不需要特意去管理。
+ W( U1 z7 z" @9 _5 }
3 g/ Q- t8 X M堆则为那些需要长期存在或者大小不确定的数据提供了存储场所。
[9 l1 C9 _! _- w9 p4 a$ G) O- c9 j( c
比如在开发一个图形绘制软件时,用户绘制的图形可能数量和大小都不确定,这时候就需要从堆中分配内存来存储这些图形数据。
- p- a# D- A) j; S% f8 M0 X2$ B3 f$ _! n7 u! g' s* z. M, ~/ d
如何理解堆和栈
' a+ v0 n$ ?$ g# c7 H6 M' U栈:高效的临时存储区: K$ K5 Q- l6 b) k
从功能上看,栈就像是一个有条不紊的办公桌面。3 T7 o' _$ x! _2 B% V9 `
0 E( z& h- X; G* J2 C# l& E8 W7 u# p
当你开始一项任务(函数调用)时,你把需要用到的工具(局部变量等)放在桌面上,任务完成后,你把工具收拾起来(内存释放)。/ j7 G; b# c% n" Y7 \6 }7 j
( i3 G6 v6 K ]$ q. K
它的特点是快速、自动管理,适合存放那些短期使用、生命周期与函数执行相关的数据。5 [% f9 C: p3 p. H7 Y6 t4 f$ l
/ c* H$ E6 r7 n2 z' Q# U
从操作方式上看,栈是 “后进先出” 的,就像一摞盘子,最后放上去的盘子会最先被拿走。7 Z0 Q& T5 S- n7 y" u1 L6 @) @
' ^( F4 [; H8 w' |: R' w每次函数调用就像是在盘子堆上放一个新盘子,函数返回时就把这个盘子拿走,恢复到之前的状态。. _ R* K* t" _$ }: I: G4 S! k
; L( X2 K" P C6 |0 j6 x堆:灵活的动态存储区
) C: e# E o1 K) A$ C堆可以想象成一个大型的储物仓库,你有一把钥匙(指针)可以打开仓库的门,存放或取出你需要的物品(数据)。1 c; k% W/ y- Z+ ]' u
# R6 s& K8 C' ` C; D
它的特点是灵活性高,可以根据需要动态分配和释放内存大小,但需要程序员手动管理内存的分配和释放,否则可能会出现内存泄漏等问题。
$ E: ~* f6 o" S: G, |' z: ]# X, M q! d1 X6 S, T c |+ K- c4 o6 v
从使用场景上看,当你需要创建一个对象或者存储一些大小不确定的数据时,就可以从堆中申请内存。
9 \/ A4 M4 D. A$ U& J+ q7 d h3 z7 F
比如在开发一个游戏时,游戏中的角色、道具等可能会不断变化,需要从堆中分配内存来存储这些动态的数据。
& [; k" G, N# e: G
arxbgaf1cej64060014155.jpg
, L% K% }/ e" D, P, u
wnf55523ywv64060014255.gif
! f% i" d$ F- J- `点击阅读原文,更精彩~ |