《从零开始带你成为JVM实战高手》 笔记一

一、第二课 Java是如何运行起来的

写好的java文件会被编译成class文件,类加载器会将class类加载到JVM中,JVM会基于自己的字节码执行引擎,来执行加载到内存中的那些类 

二、第三课 JVM的类加载机制

1、类加载过程

一个类从加载到使用会经历下面的这个过程

加载、验证、准备、解析、初始化、使用、卸载 

加载阶段:只有用到什么类,才会加载什么类

验证阶段:校验加载进来的class文件是否符合规范

准备阶段:给加载进来的类分配内存空间、类变量(static修饰的)分配内存空间、赋予初始值

准备阶段给类变量赋值,只会赋予初始值,例如private static int number = 10,那么number的值是0。除非是private static final int number = 10这样的常量,才会直接赋予10

初始化阶段:执行初始化代码,包括给静态变量赋值,执行静态代码块方法

2、类加载器和双亲委派机制

类加载主要分为:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)、应用程序类加载器(Application ClassLoader)、自定义加载器

3、思考题

问题:如何保证class文件不会被被人反编译

回答:编译时对class文件加密,在类加载时,自定义类加载器实现解密

三、JVM的内存区域

1、第四课 各内存区域讲解

方法区(jdk8前由永久代实现,jdk8后由元数据区实现):存放类信息(Kafka.class),jdk8之前方法区也存放静态变量

程序计数器:用来记录当前执行到哪一条字节码指令

虚拟机栈:每个线程会创建一个虚拟机栈

本地方法栈:每个线程会创建一个本地方法栈

栈帧:一个线程执行一个方法,就会在虚拟机栈中创建一个栈帧,栈帧内有局部变量表、操作数栈、动态链接、方法出口等

堆内存:存放创建的各种对象,对象的成员变量。jdk8之后也存放静态变量。栈帧的局部变量表只存放堆中对象的地址

堆外内存:不归JVM管的内存 ,例如NIO中的allocateDirect就可以在堆外分配内存,然后通过DirectByteBuffer来操作堆外内存

JDK8以前内存模型:

JDK8后内存模型:

元数据区并不在虚拟机中,而是使用本地内存

2、总结

JVM支持多个线程,所以写好的代码可能有多个线程并发执行不同的代码指令,因此每个线程会有一个自己的程序计数器,专门记录当前线程执行到哪一条字节码指令了。线程在执行方法时,为每个方法都得创建一个栈帧放入自己的Java虚拟机栈中去,里面有方法的局部变量

3、思考题

问题:Tomcat这种Web容器中的类加载器应该如何设计实现?

回答:

Tomcat类加载流程图

四、第五课 JVM垃圾回收机制

如果某个实例对象没有任何一个方法的局部变量指向它,也没有任何一个类的静态变量,包括常量等指向它,那么垃圾回收线程就会把这个实例对象回收掉,从内存里清除掉

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值