每日一问:简述Java 中栈与堆

每日一问:简述Java 中栈与堆


Java 中栈与堆

JVM内存划分为:栈内存、堆内存、方法区内存;

栈是一种后进先出的线性表数据结构,分为栈顶和栈底两端,仅允许在表的一端插入元素,这一端被称为栈顶,另外一端称之为栈底。栈,只有两种操作,分为入栈(压栈)和出栈(退栈);向栈中添加元素的操作叫做入栈,相反从栈中删除元素叫做出栈。

  • 特点
    只能从栈顶添加元素或者删除元素
    后进先出的数据结构,Last In First Out(LIFO)

栈帧:一个栈帧随着一个方法的调用开始而创建,这个方法调用完成而销毁。栈帧内存放者方法中的局部变量,操作数栈等数据。

Java栈也称作虚拟机栈(Java Vitual Machine Stack),JVM栈只对栈帧进行存储,压栈和出栈操作。Java栈是Java方法执行的内存模型。
总结

  1. 每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象)。对象都存放在堆区中。
  2. 每个栈中的数据(基础数据类型和对象引用)都是私有的,其他栈不能访问。
  3. 栈分为3个部分:基本类型变量,执行环境上下文,操作指令区(存放操作指令).
  4. 在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配。
  5. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

堆数据区是用来存放对象和数组(特殊的对象)。
堆内存由多个线程共享。堆内存随着JVM启动而创建。众所周知,Java中有一个很好的特性就是自动垃圾回收。垃圾回收就操作这个数据区来回收对象进而释放内存。如果堆内存剩余的内存不足以满足于对象创建,JVM会抛出OutOfMemoryError错误。

总结

  1. 存储的全部是对象,每个对象包含一个与之对应的class信息–class的目的是得到操作指令。
  2. jvm只有一个堆区(heap)被所有线程共享,堆区中不存放基本类型和对象引用,只存放对象本身。
  3. 堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。
  4. 缺点是,由于要在运行时动态分配内存,存取速度较慢。

堆和栈的区别

  • 功能不同
    栈内存用来存储局部变量和方法调用。
    而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中。
  • 共享性不同
    栈内存是线程私有的。
    堆内存是所有线程共有的。
  • 异常错误不同
    如果栈内存或者堆内存不足都会抛出异常。
    栈空间不足:java.lang.StackOverFlowError。
    堆空间不足:java.lang.OutOfMemoryError。
  • 空间大小
    栈的空间大小远远小于堆的

方法区

方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。

在Class文件中除了类的字段、方法、接口等描述信息外,还有一项信息是常量池,用来存储编译期间生成的字面量和符号引用。

在方法区中有一个非常重要的部分就是运行时常量池,它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,对应的运行时常量池就被创建出来。当然并非Class文件常量池中的内容才能进入运行时常量池,在运行期间也可将新的常量放入运行时常量池中,比如String的intern方法。

猜你喜欢

转载自blog.csdn.net/u014657752/article/details/125298468