堆和栈的区别

堆与栈

关于堆和栈的问题,对于熟悉C++的同窗来讲可能理解的比较清楚,可是因为Java的一切对象都是在堆上,所以有时候可能反而会比较迷惑,好比:php

为何要分堆和栈?程序员

堆和栈的区别是什么?编程

为何堆是线程共享的而栈不是?数组

不少懂一点Java的人甚至是懂一点编程的人都知道内存通常分为堆和栈,栈由系统进行关系,而堆由程序员本身管理,...balabala,基本任何一本语言基础书都会提到这些特色,可是你有想过为何吗?安全

为何要分堆和栈

之因此要区分堆和栈,是因为程序须要两种不一样特性的内存形似而肯定的。在C++中,新建一个对象有两种方式,静态分配动态分配微信

静态分配数据结构

通常来讲,静态分配用于初始化已知对象大小的时候,好比int a[10];若是咱们可以肯定这个数组是10个,咱们可使用这种方式。这种方式所须要的内存在编译期间便可肯定,所以操做系统即可以预先肯定所指定大小内存给变量,而且能够在变量生命周期结束后自动释放。多线程

动态分配spa

然而在某些场景下,可能须要根据某些状况来申请内存,好比int* a =new int[count];而变量count可能就来自于某个配置文件或者用户手动输入的值。这个时候操做系统就没法再预先肯定内存大小,而且不执行到new int[count]这一行代码的时候,是没法知道所要分配的内存大小,所以操做系统分出一块内存,用来进行动态分配。而且规定,动态分配的内存须要由客户端自行管理。操作系统

Java 中的堆

因为JVM规范中规定,JVM中的一切对象都存储在堆上(内存逃逸除外)。所以在Java中并不存在对象的静态分配,所以堆和栈的来源看似就很是理所固然。可是要明白,在操做系统中,堆和栈的出现的原因。

堆和栈的区别

知道了为何要区分堆和栈,再来看看堆和栈的区别。

  • 堆是运行时肯定内存大小,而栈在编译时便可肯定内存大小

    理由即是第一节中提到的,这是区分堆和栈的初衷

  • 堆内存由用户管理(Java中由JVM管理),栈内存会被自动释放

  • 栈实现方式采用数据结构中的栈实现,具备(LIFO)的顺序特色,堆为一块一块的内存

  • 栈因为其实现方式,在分配速度上比堆快的多。分配一块栈内存不过是简单的移动一个指针

  • 在JVM中,栈不会被程序员直接使用,程序员操做的通常都是堆。

  • 栈为线程私有而堆为线程共享

虽然堆和栈有这么多的区别,可是这些区别都是因为操做系统而决定的,在硬件上,他们本质都是RAM

为何堆是线程共享的而栈不是?

上面最后一点提到了栈为线程私有而堆为线程共享。这是为何呢???

其实很简单,为了解决一个问题:线程间通讯。

想要实现线程间通讯,目前有两种方法:

  • 消息传递
  • 共享内存

共享内存即是咱们所说的将堆设置为线程间共享的,这样咱们可以经过堆中的对象实现数据共享,这样便使得其余线程可以知道某个线程修改了某个数据。可是这样带来的问题可能就有线程安全问题等,可是这样作的优点便在于速度更快节约内存,Java,C#等使用这种方式

消息传递是每一个线程都私有本身的数据空间,当须要线程通讯的时候,便须要一个线程显示的给另一个线程发送具体的消息,这样作的可以让多线程更加安全,可是私有的线程空间和消息传递带来的是须要给内个线程都拷贝相同的对象,变量等,而且可能会带来效率问题。而Erlang和JoCaml即是使用消息传递式线程通讯。

尊重劳动成功,转载注明原创

参考文章:

Why do threads share the heap space?

What’s the difference between a stack and a heap?

What and where are the stack and heap?


若是以为写得不错,欢迎关注微信公众号:逸游Java ,天天不定时发布一些有关Java进阶的文章,感谢关注

相关文章
相关标签/搜索