1、前言
自从入行以来,一直没有深刻学习过JVM,虽然看过好些书、博客也有一点了解,但都不是专门讲JVM的,因此对JVM停留在浅显的了解上,没有深刻了解过,一直想深刻学习,不过想学的东西太多了,这就致使JVM成了本身的短板,前些日子在网上看到了救火大队长的《从零开始带你成为JVM实战高手》专栏正在更新中,决定借此机会好好深刻学习一下,顺便把学习心得结合之前学习的知识记录下来,加深本身的理解。java
2、JVM加载类的过程
- 加载,加载为按需加载,主线程须要用到一个类才开始加载一个类。
- 验证,简而言之就是校验class内容是否符合指定规范
- 准备,为类变量分配内存空间,并初始默认值。
- 初始化,执行类的初始化代码(静态代码块,静态赋值代码),注:初始化会检验父类是否初始化,没有则必须先初始化父类。
- 使用
- 卸载
3、类加载器
种类
- 启动类加载器-Bootstrap ClassLoader,用于加载Java核心类库-java安装目录下的lib目录下的class。
- 扩展类加载器-Extension ClassLoader,用于加载java下的一些扩展类库-java安装目录lib\ext下的class。
- 应用程序类加载器-Application ClassLoader,加载项目ClassPath下所的class。
- 自定义类加载器,本身定义的类加载器
双亲委派机制
意思就是即优先让父ClassLoader去加载。缘由是避免重复加载,保证应用的classPath下的Class对象在内存中的惟一性。web
层次图

tomcat破坏双亲委派
tomcat做为java编码的web容器,自己也是在jvm中运行,怎么让基于tomcat容器的各个web应用正常运行,使得各个web应用包含的应用的class不会乱套,必须破坏双亲委派机制,为每个web应用的class都用不一样的类加载器去加载。数据库
- tomcat的类加载器层次图

其中:数组
common、catalina、shared负责加载tomcat本身的核心类库,webApp加载web应用的class(隔离web应用引用的三方类库),jsp加载器加载JSP(每一个JSP文件都对应一个Jsp类加载器,jsp加载器支持热加载,即Jsp只要修改,就从新加载一次覆盖原来的jsp)。缓存
经过tomcat的类加载机制,能够达成如下目标:tomcat
- tomcat支持各个web引用中不一样版本的三方类库相互隔离。
- 同一个第三方类库的相同版本在不一样web应用能够共享。
- tomcat自身依赖的类库须要与应用依赖的类库隔离 。
- jsp须要支持修改后不用重启tomcat便可生效 为了上面类加载隔离和类更新不用重启,定制开发各类的类加载器。
自定义类加载器的做用
- 实际中,能够从Web服务器、数据库或缓存服务器获取bytes数组,这就不是系统类加载器能作到的了。
- 能够从不一样的路径中获取同一个类的不一样class对象,能够实现隔离,一个复杂的程序,内部可能按模块组织,不一样模块可能使用同一个类,但使用的是不一样版本,若是使用同一个类加载器,它们是没法共存的,不一样模块使用不一样的类加载器就能够实现隔离,Tomcat使用它隔离不一样的Web应用,OSGI使用它隔离不一样模块。
- 能够实现热部署。使用同一个ClassLoader,类只会被加载一次,加载后,即便class文件已经变了,再次加载,获得的也仍是原来的Class对象,而使用自定义类加载器,则能够先建立一个新的ClassLoader,再用它加载Class,获得的Class对象就是新的,从而实现动态更新。
4、JVM内存区域划分
方法区(1.8以后叫metaspace-元数据空间)
存放类的元数据信息,能够理解为反射获取的Class对象的哪些信息。服务器
程序计数器
- 记录当前执行的class文件中字节码指令的位置
- 与线程是一对一的关系,每一个线程都会有本身的一个程序计数器
栈
一个程序计数器对应一个线程、一个线程对应一个栈、一个栈由一个个栈帧组成,一个方法对应一个栈帧,栈帧包含局部变量表、操做数栈、动态连接、方法出口(至关于结束方法时须要跳转的位置)。栈帧在调用方法的时候进栈,方法结束的时候出栈。jvm
堆
- 存放对象数据(上述栈中只存在对象的引用(即堆内存中对象的地址)或基本数据类型的值)
- 全部线程共享
- 当引用变量地址数据出栈时,堆中的内存释放由JVM控制回收
其余内存区域
- 执行native方法会有线程对应的本地方法栈。
- NIO中ByteBuffer类方法:allocateDirect(int capacity)-堆外分配内存空间返回DirectBuffer,经过DirectBuffer的Api能够操做堆外内存。
图示

4、小结
这篇文章是JVM总结的第一篇博客,可能会以为有点Low,不过写这篇博客也是想从零开始学习总结一番,就这样吧。 文中大部份内容来、图片(我也本身画过,可是太丑了,就不贴了)来源于救火大队长的《从零开始带你成为JVM实战高手》专栏文章所学笔记心得,地址在下面,有兴趣的朋友能够去看看(是收费专栏,不过较便宜)。jsp
