• heap、stack


    Stack、Heap

    202204121003501

    引入

    ​ 堆和栈在平时开发中都在看不见的地方,但问题出的确是不少。在理解的时候总是有自相矛盾的点,借此梳理下相关的知识点。堆栈在不同领域有不同作用和解释,一下从编程和数据两个角度看看他们的特性。

    编程

    ​ 在编程语言环境中,内存的分配主要为:堆分配、栈分配、静态存储分配

    栈分配:有OS(操作系统)负责自动分配及释放,存放函数的参数值、局部变量等

    堆分配:用户程序手动申请和释放的,如C中malloc函数、C++及Java中new。优点是设置的变量由程序自行决定,使用灵活。但分配后要及时释放,否则会导致内存泄露。一般向Java、python都可以自动回收不在使用的变量,类似空引用等。

    静态储存分配:即全局变量,整个程序运行期间都存在,知道程序结束才释放

    堆和栈的比较

    ​ 通俗来说,堆主要来存数据,栈来执行程序。这种不同主要由各自的特点决定的:

    :在C/C++中,方法调用通过栈进行,局部变量、形参都从栈中分配内存。方法执行完毕后,退出函数时栈的内容便被销毁。要注意的是,为要执行的方法分配栈内存时,需要事先知道数据区的大小,虽然分配在运行时进行,但分配的大小是确定的,这个大小是在编译时确定,而非运行时

    :程序运行时请求系统分配给自己内存,由于系统管理内存的分配,所以分配和销毁都要占用时间,导致堆的效率较低。优点在于,编译器不必事先知道分配多少空间,也不必知道数据要保存多长时间,用堆存数据时自主性较高。面向对象的多态性,恰恰是堆的特性的运用,因为多态变量的所需空间只有运行时创建对象后才能确定。

    JVM下的堆栈

    ​ JVM是基于栈的VM,JVM会为每个新创建的线程都分配栈,它的运行就是通过对栈的操作完成的。栈以帧为单位保存线程状态,对栈仅有两种操作:以帧为单位的压栈和出栈操作。某线程正在执行的方法称为此线程的当前方法,帧也同理。当线程激活一个方法,JVM会进行压栈,而这一帧就是当前帧。方法执行期间,栈用来保存参数、局部变量、中间计算过程及其他数据。栈具有先进后出的特性。

    ​ 每个Java应用对应一个JVM,每个JVM对应一个堆。程序运行中创建的所有类实例都在该堆中,由所有线程共享。Java中分配内存是自动初始化的。对象的存储空间在堆中分配,该对象的引用在栈中分配,也就是说建立一个对象同时从两处分配空间,堆具有先进先出的特性。

    Java中的堆栈

    ​ 栈:函数中的基本类型和引用变量在栈内存中分配,若超出函数作用域后,Java会自动释放调该作用域的内存空间,并为做他用

    ​ 堆:存放由new创建的对象或数组,分配的内存由JVM的垃圾回收器管理。

    总结:堆是运行数据区,不需要代码显式释放,优势是可以动态分配内存大小,生存期也不必明确。缺点是运行时动态分配,速度较慢。栈存取速度比堆快,仅次于寄存器,数据共享。缺点是不灵活,内存大小和存活时间都要明确

    参考文章

    Java中堆和栈

    Java中堆内存和栈内存详解

    彻底理解Java中堆和栈

  • 相关阅读:
    HTML5边玩边学
    全面理解javascript的caller,callee,call,apply概念
    什么是HTTP Headers?
    Jquery的$命名冲突:
    jQuery 核心 noConflict() 方法
    js 两个小括号 ()() 的用法
    前端工程师的编码遭遇战
    Canvas之图像与文字
    Internet Explorer 9.0 新功能介绍
    firebug1.7调试实用技巧指南—web前端开发七武器
  • 原文地址:https://www.cnblogs.com/lifelikeplay/p/16133831.html
Copyright © 2020-2023  润新知