初步学习jvm底层原理

时间:2023-01-02 20:17:29
java虚拟机内存模型:


【程序计数器,虚拟机栈,本地方法栈,堆,方法区】五个主要模块


程序计数器:
主要是当前线程执行字节码的行号指示器,是线程私有的【线程私有:在每个线程内都会创建独立的相应的内存】
如果执行的是java方法,则计数器记录的是正在执行虚拟机字节码的指令地址;
如果执行的是native方法【native:java执行非java语言的代码用到的方法修饰符,只有方法名,没有具体实现,交给外部调用】,则这个计数器为空。
此内存区域是整个jvm唯一没有规定内存溢出这个异常【OutOfMemoryError】的区域。


虚拟机栈:
我们俗称jvm内存模型分为堆内存与栈内存,这是很粗糙的。
虚拟机栈其实就是栈内存主要指代的地方,这一部分内存用来存储基础数据类型的对象,以及为对内存中动态变量的引用提供一个地址,也就是java的指针。
这一部分也是【线程私有】,每个方法在执行的同时创建一个栈帧,用来存储局部变量,操作数栈,动态链表等,
随着方法执行的结束,这个栈帧也在jvm中进行了入栈与出栈的过程。
这一块可以抛出两个异常:
【*Error:线程请求的栈的深度大于虚拟机预设的深度】【OutOfMemoryError:jvm无法扩展足够内存】


本地方法栈:
与虚拟机栈很相似,但是虚拟机栈主要为java方法提供内存服务;
而本地方法栈为native方法提供内存服务。
因为native的原因,本地方法栈对栈中方法的语言,使用方式,数据结构内都没有要求,比较*,也有些虚拟机将虚拟机栈与本地方法栈和二为一。
抛出异常与虚拟机栈相同。


堆:
占用虚拟机内存最大的一块,被所有【线程共享】,启动虚拟机就会创建这一块内存区域。
这一块内存区域的唯一作用就是存放对象实例。
java堆是jvm垃圾管理收集的主要区域,因此很多时候也被称为【GC堆:划重点了!jvm面试必考的GC回收原理!!!】
这里提到了【分代收集算法:主要分为新生代和老年代,新生代是指存在这一代中的对象容易销毁,老年代的是指存在中的对象不容易销毁,因此处理垃圾算法不同】,
【OutOfMemoryError:jvm无法扩展足够内存】


方法区:
各个线程的共享区域,此点与堆相同,但是方法区主要存储的是已经被jvm加载的类的信息,常量,静态变量等。jvm规范是把方法区归为堆的一个逻辑部分,
但是却仍然有区别:根据【分代收集算法】:方法去算是【永久代】。具体介绍还要深入学习后才能了解。
【OutOfMemoryError:jvm无法扩展足够内存】


运行时常量池:
class文件中存在类的版本,属性,方法,接口等 以及运行时常量池,主要存储的是类加载编译时期生成的各种字面变量和符号引用。
【OutOfMemoryError:jvm无法扩展足够内存】


直接内存:
直接内存并不是jvm规范定义的内存区域但是,JDK1.4后加入了【NIO】这个i/o流对象,基于【通道与缓冲区】,
它可以使用native直接分配堆外内存,然后通过java堆中的一个对象作为这块内存的引用来操作。对象是【DirectByteBuffer】。
这样就避免了java与native来回复制数据,显著提供系统性能。
直接内存不受堆内存大小限制,与硬盘内存大小有关系,当内存区域大于物理内存限制时,就会【OutOfMemoryError】