写点什么

Java 入门视频教程!什么是 JVM?

发布于: 3 小时前

JVM 运行时数据区

因为 jvm 运行时的数据区对我们开发来说还是特别重要要掌握的知识所以单拎开来西说下。


  • 方法区域(Method Area)


在 Sun JDK 中这块区域对应的为 PermanetGeneration,又称为持久代。


方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为 final 类型的常量、类中的 Field 信息、类中的方法信息,当开发人员在程序中通过 Class 对象中的 getName、isInterface 等方法来获取信息时,这些数据都来源于方法区域,同时方法区域也是全局共享的,在一定的条件下它也会被 GC,当方法区域需要使用的内存超过其允许的大小时,会抛出 OutOfMemory 的错误信息。


  • 堆(Heap)


它是 JVM 用来存储对象实例以及数组值的区域,可以认为 Java 中所有通过 new 创建的对象的内存都在此分配,Heap 中的对象的内存需要等待 GC 进行回收。


堆是 JVM 中所有线程共享的,因此在其上进行对象内存的分配均需要进行加锁,这也导致了 new 对象的开销是比较大的。


Sun Hotspot JVM 为了提升对象内存分配的效率,对于所创建的线程都会分配一块独立的空间 TLAB(Thread Local Allocation Buffer),其大小由 JVM 根据运行的情况计算而得,在 TLAB 上分配对象时不需要加锁,因此 JVM 在给线程的对象分配内存时会尽量的在 TLAB 上分配,在这种情况下 JVM 中分配对象内存的性能和 C 基本是一样高效的,但如果对象过大的话则仍然是直接使用堆空间分配。


TLAB 仅作用于新生代的 Eden Space,因此在编写 Java 程序时,通常多个小的对象比大的对象分配起来更加高效。


  • JavaStack(java 的栈):虚拟机只会直接对 Javastack 执行两种操作:以帧为单位的压栈或出栈


每个帧代表一个方法,Java 方法有两种返回方式,return 和抛出异常,两种方式都会导致该方法对应的帧出栈和释放内存。


帧的组成:局部变量区(包括方法参数和局部变量,对于 instance 方法,还要首先保存 this 类型,其中方法参数按照声明顺序严格放置,局部变量可以任意放置),操作数栈,帧数据区(用来帮助支持常量池的解析,正常方法返回和异常处理)。


  • ProgramCounter(程序计数器)


每一个线程都有它自己的 PC 寄存器,也是该线程启动时创建的。PC 寄存器的内容总是指向下一条将被执行指令的饿地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。


若 thread 执行 Java 方法,则 PC 保存下一条执行指令的地址。若 thread 执行 native 方法,则 Pc 的值为 undefined


  • Nativemethodstack(本地方法栈):保存 native 方法进入区域的地址


依赖于本地方法的实现,如某个 JVM 实现的本地方法借口使用 C 连接模型,则本地方法栈就是 C 栈,可以说某线程在调用本地方法时,就进入了一个不受 JVM 限制的领域,也就是 JVM 可以利用本地方法来动态扩展本身。

JVM 垃圾回收

Sun 的 JVMGenerationalCollecting(垃圾回收)原理是这样的:把对象分为年青代(Young)、年老代(Tenured)、持久代(Perm),对不同生命周期的对象使用不同的算法。(基于对对象生命周期分析)


通常我们说的 JVM 内存回收总是在指堆内存回收,确实只有堆中的内容是动态申请分配的,所以以上对象的年轻代和年老代都是指的 JVM 的 Heap 空间,而持久代则是之前提到的 MethodArea,不属于 Heap。


GC 的基本原理:将内存中不再被使用的对象进行回收,GC 中用于回收的方法称为收集器,由于 GC 需要消耗一些资源和时间,Java 在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短 GC 对应用造成的暂停


(1)对新生代的对象的收集称为 minor GC;


(2)对旧生代的对象的收集称为 Full GC;


(3)程序中主动调用 System.gc()强制执行的 GC 为 Full GC。


不同的对象引用类型, GC 会采用不同的方法进行回收,JVM 对象的引用分为了四种类型:


(1)强引用:默认情况下,对象采用的均为强引用(这个对象的实例没有其他对象引用,GC 时才会被回收)


(2)软引用:软引用是 Java 中提供的一种比较适合于缓存场景的应用(只有在内存不够用的情况下才会被 GC)


(3)弱引用:在 GC 时一定会被 GC 回收


(4)虚引用:由于虚引用只是用来得知对象是否被 GC


  • Young(年轻代)


年轻代分三个区。一个 Eden 区,两个 Survivor 区。大部分对象在 Eden 区中生成。当 Eden 区满时,还存活的对象将被复制到 Survivor 区(两个中的一个),当这个 Survivor 区满时,此区的存活对象将被复制到另外一个 Survivor 区,当这个 Survivor 去也满了的时候,从第一个 Survivor 区复制过来的并且此时还存活的对象,将被复制年老区(Tenured。需要注意,Survivor 的两个区是对称的,没先后关系,所以同一个区中可能同时存在从 Eden 复制过来对象,和从前一个 Survivor 复制过来的对象,而复制到年老区的只有从第一个 Survivor 去过来的对象。而且,Survivor 区总有一个是空的。


  • Tenured(年老代)


年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命期较长的对象。

最后:学习总结——MyBtis 知识脑图(纯手绘 xmind 文档)

学完之后,若是想验收效果如何,其实最好的方法就是可自己去总结一下。比如我就会在学习完一个东西之后自己去手绘一份 xmind 文件的知识梳理大纲脑图,这样也可方便后续的复习,且都是自己的理解,相信随便瞟几眼就能迅速过完整个知识,脑补回来。下方即为我手绘的 MyBtis 知识脑图,由于是 xmind 文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的 MyBtis 知识脑图原件(包括上方的面试解析 xmind 文档)



除此之外,前文所提及的 Alibaba 珍藏版 mybatis 手写文档以及一本小小的 MyBatis 源码分析文档——《MyBatis 源码分析》等等相关的学习笔记文档,也皆可分享给认可的朋友!


资料领取方式:戳这里免费下载

用户头像

VX:vip204888 领取资料 2021.07.29 加入

还未添加个人简介

评论

发布
暂无评论
Java入门视频教程!什么是JVM?