JVM学习

一、JVM定义

JVM是Java Virtual Machine(java虚拟机)的缩写。引入jvm后,java语言在不同平台上不需要重新编译。jvm屏蔽了java语言与具体平台相关的信息,java语言只需要编译生成字节码就可以在多种平台上运行。

二、类加载子系统

1.作用

类加载子系统负责从文件系统或网络中加载class文件

类加载子系统只负责加载class文件,至于是否执行,由执行引擎决定

加载的类信息存放在方法区中,方法区中可能还存放运行时常量

2.类加载过程

类加载指的是将类的二进制数据读到内存中,将其放在运行时数据区的方法区内,然后堆内创建一个class对象,用来封装方法区内的数据结构,并提供访问方法区数据结构的接口。

3.类加载分类

启动类加载器

负责加载java_home/lib目录下可以被虚拟机识别的字节码文件

扩展类加载器

负责加载java_home/lib/ext目录下的字节码文件

应用程序加载器

负责加载classpath路径下的字节码

用户自定义加载器

需要继承classLoader并重写findclass方法。

4.双亲委派机制

如果一个类收到了加载请求,并不会自己加载,而是把请求交给父类加载器执行。如果父类加载器还有父类,依次向上委托,直到引导类加载器。如果顶层加载器加载成功,则成功返回。如果失败,则子类加载器会尝试加载,直到加载成功。

优点:避免类的重复加载;保护程序安全,防止核心api被篡改。

三、运行时数据区

1.内部结构

一个进程对应一个jvm实例,一个运行时数据区又包含多个线程,这些线程共享堆和方法区,每个线程包含程序计数器、本地方法栈和java虚拟机栈。

2.程序计数器

作用:用来指向下一条指令的地址,由执行引擎读取下一条指令。

3.栈

运行时的单位,解决程序的运行问题,即程序如何运行

存放基本数据类型的局部变量,以及数据类型的引用引用对象。

4.堆

存储的单位,解决数据存储的问题

对象主要存放在堆空间,是运行时数据区比较大的一块。

5.java虚拟机栈

每个线程创建时都会创建一个java虚拟机栈,其内部保存一个个栈帧,对于java一次次方法调用

作用:主管java程序的运行,保存方法的局部变量、部分结果、参与方法的调用与返回

不存在垃圾回收问题

栈的运行原理:

没个线程都有自己的栈,栈中的数据以栈帧的格式存放;

在这个线程上运行的每个方法对应各自的一个栈帧;

栈帧是一个内存区块,维系着方法执行过程中的各种数据信息;

JVM对java栈的操作有进栈和出栈;

一个线程上一个时间点上只有一个活动的栈帧。即只有当前正在执行的栈帧是有效的,被称为当前栈帧,与当前栈帧对应的方法叫做当前方法;

执行引擎运行的字节码只对当前栈帧操作;

如果该方法中调用了其他方法,对应新的栈帧会被创建出来,成为新的当前栈帧;

不同线程中包含的栈帧是不可以相互引用的;

如果当前方法调用了其他方法,方法返回之际,当前方法会传回此方法的执行结果给前一个栈帧,接着,虚拟机会丢弃当前栈帧,使得前一个栈帧重新成为当前栈帧;

java的两种返回函数的方式,一种是正常的函数返回,使用return指令,一种是抛出异常。不管哪种方式都会导致栈帧被弹出。

栈帧内部结构:

局部变量表、操作数栈、动态链接、方法返回地址、附加信息

6.本地方法接口

定义:java调用非java代码接口,该方法的实现由非java语言实现。

原因:本地方法使用起来方便,实现容易或者要求效率高。

7.堆

堆的概念

一个进程对应多个jvm实例,同时包含多个线程,这些线程共享方法区和堆,每个线程都有独立的本地方法栈、程序计数器、java虚拟机栈。

一个jvm只有一个堆内存,堆是java内存管理的核心区域。

java堆区在jvm启动时就被创建,其空间大小也被确定,是jvm最大的一块内存。

堆可以是物理上不连续的但逻辑上应该被视为连续的。

所有的对象都应该被分配在堆上。

对象不能保存在栈上,因为栈中保存引用,这个引用指向对象在堆中的位置。

在方法结束后,堆中的对象不会马上被移除,仅仅在垃圾收集的时候才会被移除。

堆是垃圾回收的重点区域。

堆的内存结构:

逻辑:年轻代(伊甸园区、幸存者0区、幸存者1区)、老年代、元空间

存储在jvm中的对象可以被划分为两类:

一种是生命周期较短的瞬时对象,这类对象创建和消亡都很快(存入新生代)

二种是对象生命周期非常长,在某些情况还能与jvm的生命周期保持一致(存入老年代)

对象分配过程:

对象分配是非常严谨的任务,需要考虑内存如何分配、分配在哪里,并且内存分配算法与内存回收算法有关,所以还需考虑垃圾回收完成后内存空间是否产生内存碎片。

(1)new的对象放在伊甸园区,此空间有大小限制。

(2)当伊甸园空间满了,程序又要创建对象,jvm垃圾回收器对伊甸园进行垃圾回收,将伊甸园区中不再被引用的对象进行销毁。将伊甸园区剩余对象放到幸存者0区。

(3)加载新的对象放在伊甸园区

(4)如果再次出发垃圾回收,此时上次幸存下来存放在幸存者0区的对象,如果没有回收会被放入到幸存者1区。

(5)如果再次垃圾回收,此时后重新放回到幸存者0区。

(6)啥时候区养老区?可以设置次数,默认15次,可以设置次数。-XX:MaxTenuringThreshold=进行设置。

(7)在养老区,当内存不足时,再次触发GC,进行养老区内存清理。

(8)若养老区发生gc之后无法清理出空间,则会触发OOM异常。

堆空间分代思想

优化GC性能:如果没有分代,所有对象放在一块,GC时需要找出哪些对象没用,这就会对堆的所有对象进行扫描,而很多对象是朝生夕死。如果分代,就可以把新创建的对象放在一个地方,当gc时就可以直接在这个朝生夕死的地方进行回收,就会腾出很大地方。

四、执行引擎

JVM主要任务是装载字节码到其内部,但字节码不能直接在操作系统上运行,因为字节码指令不等于本地机器指令。执行引擎的任务是将将字节码解释/编译成为本地机器可以执行的指令。

java语言是半编译半解释语言原因:java程序在运行之前有一个编译过程,但并不是将将编译程序转换成机器语言,而是将它编译成字节码,然后通过执行引擎将其解释为机器指令运行。

五、垃圾回收机制

1.定义:垃圾是指在程序运行过程中没有任何指针指向的对象,这个对象就需要被垃圾回收。如果这些垃圾不回收,那么这些垃圾所占用的内存会一直保留到应用程序结束,被保留的空间无法被其他对象使用,甚至导致内存溢出。

2.垃圾回收算法

对象存活判断:引用计数法和可达性分析法

引用计数法:某个对象只要被引用一次,对应的引用计数器加一,当引用失效时引用计数器减一。缺点存在循环引用问题。

可达性分析法:从根对象为起点,自上而下搜索被跟对象集合所连接的目标对象是否可达。如果目标对象没有被任何引用链相连,则表示不可达,为垃圾。

清除算法:

标记清除算法、复制算法、压缩算法

标记清除算法:容易产生内存碎片

复制算法:需要两倍的内存空间

原文:https://blog.csdn.net/qq_48435252/article/details/123697193

全部评论

相关推荐

用户64975461947315:这不很正常吗,2个月开实习证明,这个薪资也还算合理,深圳Java好多150不包吃不包住呢,而且也提前和你说了没有转正机会,现在贼多牛马公司骗你说毕业转正,你辛辛苦苦干了半年拿到毕业证,后面和你说没hc了😂
点赞 评论 收藏
分享
评论
2
18
分享

创作者周榜

更多
牛客网
牛客企业服务