Java内存模型
Java的内存模型从简单的划分上可以称为堆栈,当然堆(heap)和栈(stack)两者是不同的概念,堆的作用是用于保存Java 对象,对象的创建、销毁都是在堆中完成的;栈的作用是来执行程序的,栈中存放的是栈帧,Java中方法被调用时就会生成一个栈帧,方法的调用、执行结束在栈中的表现就是栈帧在栈中的入栈、出栈的操作。
实际的Java内存模型要更复杂一下,包括:程序计数器、虚拟机栈,本地方法栈、堆、方法区。其中程序计数器、虚拟机栈、本地方法栈这三个是线程私有的,即每个线程都有自己的对应的空间,而堆、方法区,是线程共享,每个线程都可以使用。一般还有一个常量池,常量池其实是方法区的一部分。
内存模型分析
线程私有区:
程序计数器:内存中分配的空间很小,是当前线程所执行的字节码的行号指示器,执行玩一行字节码,会修改这个值用来告诉CPU下一个执行的字节码,虚拟机中只有Java方法才会修改这值,若是调用native方法,计数器为空。
虚拟机栈:和线程同生同灭,线程创建的时候会分配虚拟机栈,每个虚拟机栈大的大小为栈内存/最大线程数,当前线程调用方法时,就会生成一个栈帧,用来保存方法的局部变量、操作数栈、动态链接、返回地址等信息,越是庞大的方法,栈帧的大小就会越大,局部变量一般是影响栈帧大小的主要因素,当前现成的虚拟机栈内存/栈帧大小也被称为栈的深度,如果方法的调用超过了栈的深度,就会导致栈溢出,常见场景是递归深度过深。
方法栈:和虚拟机栈类似,这个栈内运行的本地方法。
线程共享区:
堆:虚拟机启动时创建,用来保存Java对象的实例,一般也是虚拟机内存中最大的部分,Java对象的创建、销毁都在堆中,堆内简单划分为:新生代、老年代两个区域,新对象的创建一般在新生代,若是过大的对象一般直接生成在老年代(跟虚拟机模式、 配置、GC垃圾回收机制相关),老年带一般多次GC后仍存活的对象,这些对象一般比较稳定。新生代中细分还有Eden、from survivor、to survivor区域,新对象一般新建与Eden中,survivor区域主要用于新生代的GC回收机制(复制算法copy)。
方法区:用来保存虚拟机加载的类的类信息、静态变量、常量、编译后的代码等信息。常量池是方法区的一部分,保存着编译期间出现的字面量、符号引用及直接引用。
这部分的内容之前在学习简单学习GC时也有些道,那时候对Java模型进行了简单的了解。GC垃圾回收
本文深入解析Java内存模型,包括程序计数器、虚拟机栈、本地方法栈、堆、方法区等关键组件,并探讨了线程私有区与线程共享区的概念。此外,还详细分析了堆内存中的新生代、老年代及其GC机制。
1030

被折叠的 条评论
为什么被折叠?



