答:负责运行java编译好的字节码文件(.class),也就相当于是负责运行我们写好的系统。
答:JVM具有跨平台性,可以在多种系统上执行。
答:JVM要运行这些“.class”字节码文件中的代码,首先得把这些“.class”文件中包含的各种类给加载进来,把编译好的那些".class"字节码文件给加载到JVM中。
答:执行加载到内存里的我们写好的那些类了
过程:加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载
根据Java虚拟机规范,来校验你加载进来的“.class”文件中的内容,是否符合指定的规范
这个阶段是给加载进来的类分配好了内存空间,类变量(也就是static修饰的变量)也分配好了内存空间,并且给了默认的初始值,这个概念,大家心里一定要有。
实际上是把符号引用替换为直接引用的过程
初始化过程是执行类构造器<client>()方法的过程
类构造器client<>() 会对的所有类变量(静态变量)的赋值动作和静态语句块(static{})中的语句合并并按照出现的顺序决定的
**双亲委派模型:**先找父亲去加载,不行的话再由儿子来加载。 JVM的类加载器是有亲子层级结构的,启动类加载器最上层,扩展类加载器第二层, 应用程序类加载器第三层,自定义类加载器第四层。当应用程序类加载器需要加载一个类时, 他会先委派给自己的父类加载器去加载,最终传导到顶层的类加载器去加载,但是如果父类 加载器在自己负责加载的范围内,没找到这个类,那么就会下推加载权利给自己的子类加载器 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hj99VrjF-1572591931618)(/Users/laiyanxin/Library/Application Support/typora-user-images/image-20191027211307179.png)]
首先编译时,就可以采用一些小工具对字节码加密,或者做混淆等处理
现在有很多第三方公司,都是专门做商业级的字节码文件加密的,所以可以付费购买他们的产品。
然后在类加载的时候,对加密的类,考虑采用自定义的类加载器来解密文件即可,这样就可以保证你的源代码不被人窃取。
主要是放从“.class”文件里加载进来的类,还会有一些类似常量池的东西放在这个区域里。JDK 1.8以后叫“Metaspace”
记录当前线程执行的字节码指令的位置。每个线程都会有自己的一个程序计数器,专门记录当前这个线程目前执行到了哪一条字节码指令了
来保存每个方法内的局部变量等数据的,这个区域就是Java虚拟机栈,每个线程都有自己的Java虚拟机栈,如果线程执行了一个方法,就会对这个方法调用创建对应的一个栈帧
栈帧里就有这个方法的局部变量表 、操作数栈、动态链接、方法出口等东西。
存放我们在代码中创建的各种对象的
native方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q3cwKqsT-1572591931619)(/Users/laiyanxin/Library/Application Support/typora-user-images/image-20191027212610692.png)]
每个WebApp负责加载自己对应的那个Web应用的class文件,也就是我们写好的某个系统打包好的war包中的所有class文件,不会传导给上层类加载器去加载。
对象对内存空间的布局可以分为:对象头+实例数据+对齐填充
对象头分为两部分组成:
一个是对象自己本身的一些信息 包括hashcode,GC分代年龄,线程持有锁,锁状态标志,偏向线程ID,偏向时间戳,被称为mark word类元数据指针 指向类元数据的指针,虚拟机根据这个指针确定哪个类的实例。并不是所有虚拟机都保留类型指针。如果是数组,对象头还必须有一块记录数组的长度,因为虚拟机可以通过普通对象的元数据信息确定对象的大小,而数据的元数据是无法确定大小的。实例数据:代码中定义的类型字段内容
对齐填充:不是必然存在,对象必须是8字节的倍数,如果对象实例数据没有对齐,则通过对齐填充来补全。
对象访问方式取决于虚拟机实现而定,目前主要的方式是使用句柄和直接引用。
使用句柄就是将java堆中划分一块内存为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象的实例数据和类型数据各自的具体地址信息。
直接引用就是reference中存储的就是对象地址
这两种方式各有优势,使用句柄最大好处是稳定的句柄地址,对象移动只改变句柄中的实例数据地址,而引用变量不需要改。缺点浪费空间。直接引用访问方式就是速度块,节省了内存。 这两种方式各有优势,使用句柄最大好处是稳定的句柄地址,对象移动只改变句柄中的实例数据地址,而引用变量不需要改。缺点浪费空间。直接引用访问方式就是速度块,节省了内存。
JVM的垃圾回收机制
JVM本身是有垃圾回收机制的,他是一个后台自动运行的线程,你只要启动一个JVM进程,他就会自带这么一个垃圾回收的后台线程。这个线程会在后台不断检查JVM堆内存中的各个实例对象,已经没有任何方法的局部变量在引用这个实例对象了他就会被回收