jvm内存结构与类加载机制

一、jvm内存结构
jvm内存结构分为类加载子系统、运行时数据区和执行引擎。
1、类加载子系统:就是将.class文件加载到内存,然后再通过连接、初始化。
类加载到
2、运行时数据区:运行时的内存结构,包括堆、方法区、虚拟机栈、程序计数器和本地方法栈。

说明:方法区和堆是线程共用的一块内存,虚拟机栈、本地方法栈和程序计算器是线程私有的。
方法区:所有定义的方法的信息都保存在该区域。静态变量+常量+类信息(构造方法/接口定义)+运行时常量池,也叫非堆。
堆:用来存储对象的实例,当对象无法申请到该内存空间将抛出OutOfMemoryError异常。
在这里插入图片描述
新生代分为伊甸区和幸存区,幸存区又分为from区和to区,这两个区也叫s0区和s1区。所有新创建的对象开始在伊甸区中,当伊甸区满了之后会产生gc,幸存下来的对象会保存到幸存区中的from区,当from满了之后又会产生gc,from区幸存下来的对象将会到to区中,to区满了之后将会和from区对换,原来的from区成为了to区,原来的to区成为了from区,这个时候幸存下来的对象年龄加1,如此循环,当对象的年龄达到15后,该对象将会保存到老年代中。当老年代满了会产生fullGC。将会抛出OutOfMemoryError异常。元空间在jdk1.8后替换了永久代。

栈:java线程执行方法的内存模型,一个线程对应一个栈,每个方法执行的时候都会创建一个栈帧,每个栈帧包括局部变量表,操作数栈,动态链接和方法返回地址。线程执行完后就会释放,不存在垃圾回收的问题。
本地方法栈:和栈作用类似,java栈主要是为jvm执行java方法服务,而本地方法栈主要是为jvm执行native方法服务。
程序计数器:就是一个指针,用来记录程序下一步将执行什么。
线程在虚拟机栈中的流程:
在这里插入图片描述
例如运行下面代码

int a = 1;
int b = 2;
int c = a+b;
System.out.print(c);

虚拟机栈的流程就是,首先将1放入操作数栈,然后将1拿出来放入局部变量表中,在把2放入操作数栈中,在拿出来放入局部变表,操作数栈是先进后出的。然后把1和2复制一份放入操作数栈,拿出放到执行引擎中执行得到的结果先放到虚拟栈中,在放入局部变量表中,然后就是把c复制到操作数栈中,通过返回地址返回。
每一个方法都是一个栈帧,当前方法就是当前栈帧。动态连接就是将符号引用转为直接引用。符号引用可以将.class文件反汇编javap -c命令查看。

二、类加载机制
1、类的生命周期:
在这里插入图片描述
加载:将.class文件读到内存
验证:验证字节码文件的正确性
准备:给类的静态变量分配内存,并赋值。
解析:类装载器装入类所引用其他所有类。
初始化:为类的静态变量赋予正确的初始值,上述的准备阶段为静态变量赋予的是虚拟机默认的初始值,此处赋予的才是程序编写者为变量分配的真正的初始值,执行静态代码块。

2、类加载器种类
启动类加载器:负责加载jre的核心类库,如rt.jar
扩展类加载器:负责加载扩展目录中ext目录中的jar包
系统类加载器:用于加载classpath目录下的类包
自定义类加载器:负责加载用户自定义路径下的类包

类加载机制
全盘负责委托机制:当一个ClassLoader加载一个类的时候,除非显示的使用另一个ClassLoader,该类所依赖和引用的类也由这个ClassLoader载入
双亲委派机制:指先委托父类加载器寻找目标类,在找不到的情况下载自己的路径中查找并载入目标类
在这里插入图片描述
1-类加载器收到类加载的请求;
2-把这个请求委托给父加载器去完成,一直向上委托,直到启动类加载器;
3-启动器加载器检查能不能加载(使用findClass()方法),能就加载(结束);否则,抛出异常,通知子加载器进行加载。
4-重复步骤三;。
沙箱安全机制:比如自己写的String.class类不会被加载,这样可以防止核心库被随意篡改
避免类的重复加载:当父ClassLoader已经加载了该类的时候,就不需要子ClassLoader再加载一次

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值