堆与栈是java中绕不过去的内存原理之一,详细了解它们是非常有必要的,下面就小编来介绍介绍它们。
栈内存
如图,我们可以看到,在Java栈中存放的都是一个个的栈帧,而每个栈帧又对应着一个被调用的方法,在栈帧中,包含着局部变量表、指向当前方法所属的类的运行时常量池、操作数栈、方法返回地址与一些额外附加信息。
每当线程执行一个方法时,它就会跟着创建一个对应栈帧,并把建立的栈帧压栈。方法执行完毕后,再把栈帧出栈。
由此我们可知,线程与当前所执行的方法对应的栈帧是必定位于Java栈顶部的。因此对于所有的程序设计语言而言,栈这部分空间对开发者来说是不透明的。
栈内存的大小是有两种设置,它的固定值和根据线程需要动态增长。
在JVM栈这个数据区可能会发生抛出两种错误。
1、StackOverflowError 出现在栈内存设置成固定值的时候,当程序执行需要的栈内存超过设定的固定值会抛出这个错误。
2、OutOfMemoryError 出现在栈内存设置成动态增长的时候,当JVM尝试申请的内存大小超过了其可用内存时会抛出这个错误。
堆内存
在java中,堆数据区是用来存放对象和数组的。
堆内存是多个线程共享的。
JVM启动后堆内存会随之创建。
我们都知道,Java中有一个非常好的特性,自动垃圾回收。垃圾回收会操作这个数据区来回收对象从而释放内存。但如果堆内存剩余的内存不足以满足于对象创建时,JVM虚拟机就会抛出OutOfMemoryError错误。
总结:
1、 在jvm中只会有一个堆区被全部线程共享,堆区中不会存放基本类型与对象引用,只会存放对象本身。
2、堆的优势之一就是能够动态地分配内存大小,它的生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,而Java的垃圾收集器就会自动收走这些不再使用的数据。但它有个缺点:因为是在运行时动态分配内存的,所以存取速度会比较慢。
3、在堆中存储的全部都是对象,所有对象间都包含一个与之对应的class信息–class的目的就是得到操作指令。
以上就是今天的所有内容,对一些java常见问题及解决方法还有不了解的小伙伴们,可以持续关注我们了解详情。
推荐阅读: