方法区:
方法区是亮色,代表线程共享,存在垃圾回收机制。
方法区供各线程共享的运行时内存区域。它存储了每一个类的结构信息(类的模板),例如运行时常量池(Runtime Constant Pool)、字段和方法数据、构造函数和普通方法的字节码内容。上面讲的是规范,在不同虚拟机里头实现是不一样的,最典型的就是永久代(PermGen space)和元空间(Metaspace)。 但是实例变量存在堆内存中,和方法区无关。
栈开头:
栈管运行,堆管存储。
程序 = 算法 + 数据结构。(书面上)
程序 = 框架 + 业务逻辑。 (工作上)
队列(FIFO):
栈(FILO):栈也叫栈内存,主管Java程序的运行,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束该栈就Over,生命周期和线程一致,是线程私有的。8种基本类型的变量+对象的引用变量+实例方法都是在函数的栈内存中分配。
栈保存那些:8种基本类型的变量、对象的引用变量、实例方法都是在函数的栈内存中分配。
方法就是栈针。在java中叫方法,在压入栈之后就叫栈针。栈中第一个栈针一定是main,而且栈中,先进的后出,后进的先出,所以main栈针肯定最后出栈。
栈针中主要保存3类数据:
本地变量(Local Variables):输入参数和输出参数以及方法内的变量;
栈操作(Operand Stack):记录出栈、入栈的操作;
栈帧数据(Frame Data):包括类文件、方法等等。
栈运行原理:
栈中的数据都是以栈帧(Stack Frame)的格式存在,栈帧是一个内存区块,是一个数据集,是一个有关方法(Method)和运行期数据的数据集,当一个方法A被调用时就产生了一个栈帧 F1,并被压入到栈中,
A方法又调用了 B方法,于是产生栈帧 F2 也被压入栈,
B方法又调用了 C方法,于是产生栈帧 F3 也被压入栈,
……
执行完毕后,先弹出F3栈帧,再弹出F2栈帧,再弹出F1栈帧……
遵循“先进后出”/“后进先出”原则。
每个方法执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息,每一个方法从调用直至执行完毕的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。栈的大小和具体JVM的实现有关,通常在256K~756K之间,与等于1Mb左右。
栈异常:
StackOverflowError错误,这不是异常,因为有可能是递归来让内存溢出,出现错误。异常或错误通常继承的是Throwable父类,异常为Exception,错误是Error。
所以这个走的是错误分支。
栈、堆、方法区的交互关系:
Java栈的本地变量表存着对象的地址,实例化对象的时候将对象实例数据保存在JAVA堆,到对象类型数据的指针从方法区里的元空间找到被保存对象类型数据。