jvm初学篇

1.jvm简介
jvm是java虚拟机,就是java程序运行时需要的环境。
2.类装载器
类的加载 加载过程:加载->验证->准备->解析->初始化
类的加载器 启动类加载器,扩展加载器,系统加载器,自定义加载器
在这里插入图片描述
双亲委派机制(啃老) 在加载类时,先将这个类向上传递到父类,依次递归,如果父类可以加载,成功返回,如果父类不能执行就自己加载执行
3.jvm区域划分
一般来说jvm可以划分为一下几个部分
程序计数器 简单来说就是当前线程执行的字节码的行号指示器
如果线程正在执行的是Java 方法,则这个计数器记录的是正在执行的虚拟机字节码指令地址
如果正在执行的是Native 方法,则这个技术器值为空(Undefined)
此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域
java堆
1.8之前:JVM内存分为堆内存和非堆内存,堆内存分为年轻代(Young Generation)、老年代(Old Generation),非堆内存就一个永久代(Permanent Generation)。1.8之后没有永久代,原因是为了为融合HotSpot JVM与JRockit VM(新JVM技术)而做出的改变,因为JRockit没有永久代。使用元空间代替永久代,有了元空间就不再会出现永久代OOM问题了,元空间和永久代的区别在于永久代存在于jvm中,元空间存在于本地内存,需要注意最大值和最小值。
年轻代又分为伊甸区和存活区(分为两块,是为了解决碎片化问题,也就是两个对象占用不连续的内存,已有的连续内存不够新对象存放,就会触发GC。),伊甸区放的都是新生的对象,默认比例为8:1:1,新生成的对象首先放到年轻代Eden区,当Eden空间满了,触发Minor GC,存活下来的对象移动到Survivor0区,Survivor0区满后触发执行Minor GC,Survivor0区存活对象移动到Suvivor1区,这样保证了一段时间内总有一个survivor区为空。经过多次Minor GC仍然存活的对象移动到老年代。
老年代存储长期存活的对象,占满时会触发Major GC=Full GC,GC期间会停止所有线程等待GC完成,所以对响应要求高的应用尽量减少发生Major GC,避免响应超时。
Minor GC : 清理年轻代
Major GC : 清理老年代
Full GC : 清理整个堆空间,包括年轻代和永久代
所有GC都会停止应用所有线程。
在堆空间中的对象有三种状态 可触及态(可以访问到这个对象),可复活态(这个对象的引用都被释放了,但是有可能在finalize()中再次引用复活),不可触及态(这个对象的引用都被释放了,对象在finalize()中没有被复活)
GC算法:
标记-清除法:先标记所有的可清除对象,完成后一起删除,但是会产生碎片,造成在插入下个对象太大时无法找到连续内存再次触发GC
复制法:将内存分为两块,每次只使用其中的一块,在一块的内存用完时,将存活的对象复制到另一块内存中,将第一块全部清空,不用担心碎片问题,但是需要两倍的内存空间。
标记-整理法:先标记所有可清除对象,然后将存活的对象向一端移动,之后清除掉边界以外的内存
java栈
每个JVM线程拥有一个私有的 Java虚拟机栈,创建线程的同时栈也被创建。一个JVM栈由许多帧组成,称之为"栈帧"。JVM中的栈和C等常见语言中的栈比较类似,都用于保存局部变量和部分计算结果,同时也参与方法调用和返回。
当一个新的线程创建时,JVM会为这个线程创建一个新的Stack。一个Java Stack在一个个独立的栈帧中存储了线程的状态。JVM只会在Java Stack中做两个操作:push 和 pop.
一个线程当前正在执行的方法称之为线程的 当前方法,当前方法对应的栈帧称为 当前帧,当前方法所属的类称为 当前类,当前类的常量池称为 当前常量池。 在执行一个方法时,JVM会保存当前类和当前常量池的轨迹。当JVM执行 需要操作栈帧中数据的指令时,JVM会在当前栈帧进行处理。
当一个线程执行一个Java方法时,JVM将创建一个新的栈帧并且把它push到栈顶。此时新的栈帧就变成了当前栈帧,方法执行时,使用栈帧来存储参数、局部变量、中间指令以及其他数据。
总结:当一个线程被创建时就会创建一个栈帧,栈中存放的是栈帧,当方法被执行时,一个新的栈帧被创建并用来给这个方法存储数据;栈帧大小各不相同,取决于方法的参数、局部变量和算法;当一个方法被执行时,程序只能访问当前栈帧中的数据,你能看到的只有栈顶的帧
本地方法栈
本地方法栈服务的对象是JVM执行的native方法,而虚拟机栈服务的是JVM执行的java方法。
方法区
主要存放已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
方法区:所有线程共享的内存区域 ,保存系统的类信息 ,类的字段、方法、常量池等
方法区大小:决定了系统可以保存多少个类 ,如果,系统定义了太多的类,导致方法区溢出 ,JVM就会抛出内存溢出
线程共享:堆、方法区,是线程共享的 ,栈,不是线程共享的 ,每一个线程会分配一个独立的栈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值