本片博文本来是打算写一篇关于栈内存和堆内存的博文,也相当于自己的一个学习记录,结果一不小心学多了…就一直写到了内存的讲解了,本来还写了寄存器和一些硬件存储的,结果篇幅太大了就先删掉了,这里就先说下内存好了o(  ̄︶ ̄)o, 文中肯定有许多有问题不足的地方,需要各位网友大大们评论补充!
内部存储器(Internal Storage)
1.线程私有存储区(Thread-Private Storage)
1.1 栈内存(Stack)
/|————————————————|\
栈 / |____局域变量区____| \
帧 \ |_____操作数区_____| \
/ \|_____帧数据区_____| \
/ \
/ |—————————————————| \ <_________________________>\
栈 / |____局域变量区_____| \<_______PC Register_______> \包含寄存器的
内存\ |_____操作数区______| /<________JVM Stack________> /单线程内存区
\ |_____帧数据区_____| / <___Native Method Stack___>/
\ /
\ |—————————————————| /
\ |____局域变量区____| /
\ |_____操作数区_____| /
\|_____帧数据区_____|/
-
存储类型
1.基本数据类型 2.对象的引用 3.方法的调用
-
共享机制
栈内数据共享,但线程私有
-
作用时期
在代码运行时,每当调用一个方法,都在在栈内存中创建一个栈内存块(栈帧),方法结束后栈内存变成未使用的状态
-
描述
存储基本数据类型以及对象的引用,当在一个代码块中定义一些变量的时候,栈内存中为这些变量分配空间,按照 FILO 的原则,当代码块结束时,JVM 会自动释放分配的空间。栈内存不是 GC 回收的,堆内存是的。它是由编译器自动分配和释放。可能会抛出
OutOfMemoryError
和StackOverFlowError
异常。它的存取速度很快仅次于寄存器,与堆内存相比较栈内存大小很小。可用-Xss
JVM 的选项来定义栈内存大小 -
特点
存取速度很快,比堆要快,速度仅次于寄存器,存在栈中的数据有明确的生存周期和数据大小。存储其中数据可共享,线程私有
-
一些问题
-
栈内存存储方法的调用怎么理解?
答:如
f1()
方法,其中调用了f2()
方法,那么栈内存中最下层是f1()
,再上面是f2()
-
栈内存存储对象的引用怎么理解?
答:栈中保存的是对象的引用,该引用指向的是堆内存中对象中的数据。对象的引用是指向一个已创建的对象或者
null
,其只能是唯一指向,对象的引用某一时刻只能有唯一指向,对象本身可以同时被多个引用变量引用 -
栈内存如何存储数组?
答:和对象存储一致
-
什么叫做栈中数据是共享的?
答:假如有有如下代码
int a = 1; int b = 1;
java 编译器先处理
a = 1
,栈中会去找有没有值是 1 的空间,若有将 a 的引用直接指向这个空间,没有就在栈中开辟一个空间存储 1,然后执行b = 1
,这时候直接让 b 的引用指向 a 指向的空间,这样 a 和 b 的引用指向同一个空间,但对象实际上是不同的,因为假使两个对象的引用指向的是同一个对象,如果一个对象的引用变量改变了,那么这个对象的内部状态实际上也改变了 -
为什么栈内存线程私有?
答:栈内存不适合多线程共享(注意这和栈中数据共享是两个概念),因为若栈内存采用多线程共享,会非常凌乱
-
StackOverFlowError
和OutOfMemoryError
区别?答:
StackOverFlowError
栈溢出是单个线程请求栈内存大于虚拟机允许内存时候报出的,而OutOfMemoryError
内存溢出是指整个虚拟机内存耗尽,无法再申请新的内存时候报出 -
堆内存由 GC 管控,那栈内存回收呢?为什么没用 GC 管控?
答:栈内存也是 JV
-