【JVM虚拟机】JVM基础知识及工作过程

JVM基础知识

1、java跨平台解释

一次编译 到处运行
Java是一种高级语言,要让计算机执行你撰写的Java程序,也得通过编译程序的编译。但是Java编译程序并不直接将Java源代码编译为相依于计算机平台的0、1序列,而是将其编译为字节码。
java源代码的扩展名文件为.java,经过编译程序编译后生成扩展名为.class的字节码文件,如果要执行字节码文件,目标平台必须安装JVM,JVM会将字节码文件翻译于相依于平台的计算机指令,如0,1序列。

1、JVM是java程序的操作系统,JVM执行的是字节码文件。
2、JVM屏蔽了操作系统之间的差异,不同的操作系统的JVM不同。

2、JVM: java虚拟机(Java Virtual Machine)

是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台。
使用JVM就是为了支持与操作系统无关,实现跨平台。

3、JRE/JDK/JVM是什么关系

*JRE:java平台,所有的java程序都必须安装在JRE下,才能运行
*JDK:开发者用来编译,调试java程序的开发工具包
*JVM:JRE的一部分
在这里插入图片描述

4、JVM的生命周期

JVM负责运行一个java程序,启动java程序,JVM实例产生,JVM实例通过调研某个初始类main()方法运行一个java程序

5、守护线程和非守护线程

守护线程通常是由虚拟机自己使用的,比如执行垃圾收集任务的线程,java程序也可以把创建的线程标记为守护线程。
而java程序中的初始线程——main()的线程是非守护线程。
只要有任何非守护线程在运行,那么这个java程序也在继续运行,当该程序中的所有的非守护线程都终止时,虚拟机实例退出。

JVM的工作过程

1、类加载机制

java源文件——编译器——字节码文件(.class文件)——JVM——机器码
当一个程序从开始运行,这时虚拟机已经开始实例化了,多个程序启动就会存在多个虚拟机实例。程序退出或关闭,则虚拟机实例消亡,多个实例之间的数据不能共享

java类的加载是动态的,不会一次性将所有类全部加载后再运行,按需加载

1)主动初始化的六种方式(class文件加载到JVM中)

a.创建对象实例:new
b.调用静态属性或为静态属性赋值
c.调用类的静态方法
d.通过.class文件反射创建对象
e.初始化一个类的子类:使用子类的时候先初始化父类
f.java虚拟机启动时被标注为被标注为启动类的类:比如main方法所在的类

2)不会进行初始化的情况

a.在同一个类加载器下面只能初始化一次,如果已经初始化了就不用再初始化了
b.编译的时候能确定下来的静态变量(编译常量),不会再对类进行初始化。比如final修饰的静态变量

2、类加载器

A、Bootstarp ClassLoader:启动类加载器
负责加载Java-Home中 jre/lib/rt.jar里的class
B、ExtenSion ClassLoarder:扩展类加载器
负责加载java平台中扩展功能的一些jar包,包括Java-Home中jre/lib/*.jar或-Djava.ext/**.jar
C、AppClassLoader :应用类加载
负责加载CLASSPATH 指定的所有jar包和目录

双亲委派模型
在这里插入图片描述
优点:
(1)安全性:避免用户自己编写的类动态替换了java的一些核心类
(2)避免重复加载

3、类加载的注解过程

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

单例设计模式

class Single{
   private static Object instance;
   static{
       instance=new Object();
   }
   public static Single getInstance(){
      return  instance;
   }
}

使用时 Single.getInstance()
问:这个单例是安全的吗?
答:安全,和类的加载过程有关,在准备阶段将内存分配出来,初始化阶段实例出来,使用时已经创建出来,不需要再创建

4、java内存模型

主要从(功能,是否线程共享,生命周期,抛出异常)来考虑
1、程序计数器(线程私有)
每个线程都需要一个独立的程序计数器,这是一块非常小的内存空间,可以看做当前线程所执行的字节码的行号指示器。
作用:(1)字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制。如:顺序执行,选择循环,异常处理。
(2)在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行的位置。
注:程序计数器是唯一一个不会出现OutOfMemoryError的内存区域
程序计数器的生命周期随着线程的创建而创建,随着线程的结束而死亡

2、java虚拟栈(线程私有)
由一个个栈帧组成(每一个方法类似栈帧)
栈帧由【局部变量表】————(八大原始类型)(对象引用)(return Address)组成
【操作数栈】
【动态链接】
【方法出口信息】
栈帧会出现两种异常:
1):StackOverFlowError(栈溢出异常):当java虚拟机栈的内存不允许动态扩展,当线程请求栈的深度超过当前java虚拟机栈的最大深度,则抛出。
2):OutOfMemoryError:当java虚拟机栈的内存大小允许动态扩展,且当线程请求栈时内存已经用完了,无法动态扩展则抛出。
在这里插入图片描述
3、本地方法栈
和虚拟机栈发挥的作用相似 也会抛出StackOverFlowError OutOfMemoryError异常
区别:虚拟机栈为虚拟机执行java方法(也就是字节码服务),而本地方法栈则为虚拟机使用到的Native方法服务。
4、堆
java虚拟机下所管理的最大的一块,java堆是所有线程共享的一块内存区域,在虚拟机启动时创建。
目的:存放对象实例,几乎所有的对象实例以及数组都在这里分配内存
java堆是垃圾收集器管理的主要区域,因此也被称作GC堆

常量池分为新生代 老年代 永久代
jdk1.6及之前,常量池分配永久代
jdk1.7,有但已经逐步去永久代
jdk1.8,无,取而代之的是一个叫“元空间”的区域
(永久代使用的是JVM堆内存空间,而元空间使用的是物理内存,直接变到本机的物理内存限制)

5、方法区
和java堆一样,各个线程共享的是内存区域,用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码与数据
java虚拟机规范把方法区描述为堆的一个逻辑部分,它有一个别名叫非堆,需要与java堆分开

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值