当前位置: 首页 > 编程笔记 >

简述JAVA中堆内存与栈内存的区别

谭琛
2023-03-14
本文向大家介绍简述JAVA中堆内存与栈内存的区别,包括了简述JAVA中堆内存与栈内存的区别的使用技巧和注意事项,需要的朋友参考一下

Java把内存划分成两种:一种是栈内存,一种是堆内存。

一、栈内存

      存放基本类型的变量,对象的引用和方法调用,遵循先入后出的原则。
      栈内存在函数中定义的“一些基本类型的变量和对象的引用变量”都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

        Java中的代码是在函数体中执行的,每个函数主体都会被放在栈内存中,比如main函数。假如main函数里调用了其他的函数,比如add(),那么在栈里面的的存储就是最底层是main,mian上面是add。栈的运行时后入先出的,所以会执行时会先销毁add,再销毁main。

        栈的优势是,栈内存与堆内存相比是非常小的,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄。栈有一个很重要的特殊性,就是存在栈中的数据可以共享。

二、堆内存

     存放所有new出来的对象和数组

     特此强调,堆内存和数据结构中的堆完全是两码事,分配方式倒是类似于链表

     堆内存是区别于栈区、全局数据区和代码区的另一个内存区域。堆允许程序在运行时动态地申请某个大小的内存空间,堆内存实际上指的就是(满足堆内存性质的)优先队列的一种数据结构,第1个元素有最高的优先权。

      在堆内存分配时首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。

       另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。堆内存是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆内存的大小受限于计算机系统中有效的虚拟内存。由此可见,堆内存获得的空间比较灵活,也比较大。堆内存是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。

       栈与堆都是Java用来在Ram中存放数据的地方。与C ++不同,Java自动管理栈和堆,程序员不能直接设置栈或堆

       Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过新的,newarray,anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

三、其他数据存储

    1、常量池:存放基本类型常量和字符串常量(public static final)
    2、静态域:存放静态成员(static定义的)
    3、非RAM存储:硬盘等永久存储空间

堆内存和栈内存的区别:

   1、应用程序所有的部分都使用堆内存,然后栈内存通过一个线程运行来使用。
   2、不论对象什么时候创建,他都会存储在堆内存中,栈内存包含它的引用。栈内存只包含原始值变量好和堆中对象变量的引用。
   3、存储在堆中的对象是全局可以被访问的,然而栈内存不能被其他线程所访问。
   4、栈中的内存管理使用LIFO的方式完成,而堆内存的管理要更复杂了,因为它是全局被访问的。
   5、栈内存是生命周期很短的,然而堆内存的生命周期从程序的运行开始到运行结束。
   6、我们可以使用-Xms和-Xmx JVM选项定义开始的大小和堆内存的最大值,我们可以使用-Xss定义栈的大小
   7、当栈内存满的时候,Java抛出java.lang.StackOverFlowError异常而堆内存满的时候抛出java.lang.OutOfMemoryError: Java Heap Space错误
   8、和堆内存比,栈内存要小的多,因为明确使用了内存分配规则(LIFO),和堆内存相比栈内存非常快。

总结:

   1 栈:为编译器自动分配和释放,如函数参数、局部变量、临时变量等等

   2 堆:为成员分配和释放,由程序员自己申请、自己释放。否则发生内存泄露。典型为使用new申请的堆内容。
        除了这两部分,还有一部分是:

   3 静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。

以上就是简述JAVA中堆内存与栈内存的区别的详细内容,更多关于JAVA中堆内存与栈内存的资料请关注小牛知识库其它相关文章!

 类似资料:
  • 本文向大家介绍Java 堆内存与栈内存详细介绍,包括了Java 堆内存与栈内存详细介绍的使用技巧和注意事项,需要的朋友参考一下  Java 中的堆和栈 Java把内存划分成两种:一种是栈内存,一种是堆内存。 ​ 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉

  • 本文向大家介绍java中堆内存与栈内存的知识点总结,包括了java中堆内存与栈内存的知识点总结的使用技巧和注意事项,需要的朋友参考一下 一、概述 在Java中,内存分为两种,一种是栈内存,另一种就是堆内存。 二、堆内存 1、什么是堆内存? 堆内存是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对象或者创建一个数组的时候,就会在堆内存中开辟一段空间给它,用于存放。

  • 本文向大家介绍java 中堆内存和栈内存理解,包括了java 中堆内存和栈内存理解的使用技巧和注意事项,需要的朋友参考一下  Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存

  • 本文向大家介绍Java中的堆栈和堆内存之间的区别,包括了Java中的堆栈和堆内存之间的区别的使用技巧和注意事项,需要的朋友参考一下 JVM将内存空间分为两部分,一个是堆栈,另一个是堆空间。堆栈空间主要用于存储方法执行的顺序和局部变量。 堆栈始终按照LIFO顺序存储块,而堆内存使用动态分配来分配和取消分配内存块。  分配给堆的内存将一直存在,直到发生以下事件之一: 程序终止  无记忆  相反,分配给

  • 我们Java开发人员有时会使用来确保我们为每个特定于线程的堆栈提供了1MB的空间。现在,我经常感到困惑,JVM从哪里借用了1MB,从堆或系统内存中借用,或者Java为线程分配任何特定的内存。你能帮我理解一下吗? 此外,我们是否有一个可视化(插件)运行时工具,可以以可理解的方式显示堆和堆栈的内容? 提前感谢。

  • 问题内容: 是局部变量,将其存储在堆或堆栈中的何处? 问题答案: 在堆上。每当您用来创建对象时,它都会在堆上分配。