Java 虚拟机(JVM (Java Virtual Machine))

1、Java 程序的编译和运行过程
  • 如下图所示:
    Java 程序的编译和运行过程图
2、Java 运行时内存区域类型
  • Java 内存区域图如下:
    Java 内存区域图
  • JVM 所管理的内存分为以下几个运行时数据区:方法区、Java 虚拟机栈、本地方法栈、Java 堆、程序计数器。
  • 方法区:线程共享,所有已经被虚拟机加载的类的信息、常量、静态变量和即时编辑器编译后的代码数据。
  • Java 虚拟机栈:线程私有,面 向java,描述 Java 方法执行的内存模型,每个方法在执行的同时会创建一个栈帧,存储着局部变量、操作数栈、动态链接和方法出口等,线程私有。
  • 本地方法栈:线程私有,面向 native,本地方法执行的内存模型。
  • Java 堆:线程共享,所有对象实例以及数组都要在堆上分配。是垃圾收集管理器的主要区域,因此也被称为“GC 堆”。
  • 程序计数器:线程私有,记录当前线程的字节码执行位置的指示器,为线程切换用。
3、Java 内存模型(JMM:java memory model)
  • Java 内存模型的目的:屏蔽掉各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果。

  • Java 内存模型规定了所有的变量都存储在主内存中,每条线程中都有自己的工作内存,线程的工作内存中保存了被该线程所使用到的变量(这些变量都是从主内存中拷贝而来),线程对变量的所有操作(读取、赋值)都必须在工作内存中进行。不同线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。
    Java 内存模型抽象结构示意图

  • 主内存和工作内存之间的交互协议,即变量如何从主内存传递到工作内存,工作内存又如何将变量传递到主内存,Java 内存模型定义了 8 种操作来完成,并且每一种操作都是原子的,不可再分的。

类型说明
lock(锁定)作用于主内存的变量,把一个变量标识为一条线程独占的状态
unlock(解锁)作用于主内存的变量,把一个处于锁定的变量释放出来
read(读取)把一个变量的值从主内存传输到工作内存中,以便随后的 load 使用
load(载入)把 read 操作从主内存中得到的变量值放到工作内存的变量副本中
use(使用)把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时执行这个操作
assgin(赋值)把一个从执行引擎中接收到的值赋值给工作内存中的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作
store(存储)把工作内存中的一个变量的值传递到主内存,以便随后的 write 使用
write(写入)把 store 操作从工作内存中得到的变量值放入到主内存的变量中
4、String s1 = “abc” 和 String s2 = new String(“abc”) 的区别和生成对象的情况?
  • 指向方法区:“abc” 是常量,所以它会在方法区中分配内存,如果方法区已经给 “abc” 分配过内存,则 s1 会直接指向这块内存区域。
  • 指向 Java 堆:new String(“abc”) 是重新生成了一个 Java 实例,它会在 Java 堆中分配一块内存。
5、类加载过程
  • Java 类加载过程图:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aVXlZqoE-1646989181172)(https://note.youdao.com/yws/res/27712/WEBRESOURCE9eea7f8f104724a3dd4e6f0458ee090b)]
  • 加载:将类的全限定名转化为二进制流,再将二进制流转化为方法区中的类型信息,从而生成一个 Class 对象。
  • 验证:对类的验证,包括格式、字节码、属性等。
  • 准备:为类变量分配内存并设置初始值。
  • 解析:将常量池的符号引用转化为直接引用。
  • 初始化:执行类中定义的 Java 程序代码,包括类变量的赋值动作和构造函数的赋值。
  • 注意:只有加载、验证、准备、初始化和卸载的这个五个阶段的顺序是确定的。
5、类加载机制,为何这样设计?
  • 类加载的机制是双亲委派模型。大部分 Java 程序需要使用的类加载器包括:
  • 启动类加载器:由 C++ 语言实现,负责加载 Java 中的核心类。
  • 扩展类加载器:负责加载 Java 扩展的核心类之外的类。
  • 应用程序类加载器:负责加载用户类路径上指定的类库。
  • 双亲委派模型如下:
    Java 双亲委派模型图
  • 双亲委派模型要求出了顶层的启动类加载器之外,其他的类加载器都有自己的父加载器,通过组合实现。
  • 双亲委派模型的工作流程:当一个类加载的任务来临的时候,先交给父类加载器完成,父类加载器交给父父类加载器完成,直到传递给启动类加载器,如果完成不了的情况下,再依次往下传递类加载的任务。
  • 这样设计的原因:
  • (1)避免重复加载,父类已经加载了,则子 CLassLoader 没有必要再次加载。
  • (2)考虑安全因素,双亲委派模型能够保证 Java 程序的稳定运行,不同层次的类加载器具有不同优先级,所有的对象的父类 Object,无论哪一个类加载器加载,最后都会交给启动类加载器,保证安全。
6、什么是垃圾回收(GC)?
  • 它是 Java 语言的一种自动存储管理机制,它把内存释放的工作都交给了系统,它不像 C/C++ 一样其内存的释放工作需要我们手动去进行操作。其回收原理是当一个对象已经不需要使用了,且没有另外一个正在使用的对象持有它,那么当GC回收的时候就可以对当前对象进行垃圾回收。
7、Java GC 回收流程?
(1)可回收对象的判定
  • 第一步:引用计数算法=>首先给每个对象都添加一个引用计数器,当程序的某个地方引用了这个对象,计数器就进行值 +1 操作,当引用失效之后计数器进行值 -1 操作,当某个对象的计数器值为 0 时,就判定这个对象不可能被使用。但是这里有个缺点就是互相引用的对象无法被回收。
  • 第二步:GC Root 可达性分析算法=>已称作“GCRoot”的对象作为起点向下搜索,每走过一个对象,就生成一条引用链,从而搜索完成之后生成一颗引用树,那些到 GCRoot 不可达的对象就是可以回收的。这里主要是为了解决上面一步未解决的循环引用问题。
  • 可作为 GC Root 对象的有
  • (1)Java 虚拟机栈中的局部变量(变量指向一个对象)
  • (2)本地方法栈中 JNI(native 修饰的方法指向的对象)
  • (3)方法区中的静态属性(静态属性指向一个对象)
  • (4)方法区中的常量(常量指向一个对象)
(2)通过算法回收垃圾内存
  • 标记-清除算法=>首先标记可回收的内存,然后再对内存进行回收。但是这样有两个不足之处,首先它的效率不是很高,其次标记-清除算法之后会产生大量不联续的空间碎片,基于这样的不足,然后有了标记-整理算法。
  • 标记-整理算法=>首先对存活对象进行标记,然后将存活对象向一端移动,然后对另外一端的内存进行清除。这样的好处就是产生了连续的空间。
  • 复制算法=>它是将内存平分成两个区域,将第一个区域存活的对象复制到第二个区域中去,然后将第一个区域的所有对象清除,这样第一个区域就是一个完整的内存块,从而避免了内存碎片化。
  • 分代回收算法=>严格意义来说它并不是一个新的算法,它只是上面几种算法的整合方案。堆内存中有新生代区域和老年代区域,新生代区域中每次垃圾回收都要回收大部分对象,存活对象较小,比较适合使用复制算法进行内存回收,而老年代区域每次回收都只能回收很少的对象,比较适合使用标记清除算法和标记整理算法。
8、Minor GC 与 Full GC 的区别?
  • Minor GC:频率高、针对新生代。
  • Full GC:频率低、发生在老年代、通常会伴随一次 Minar GC(指对年老代的回收)和速度慢。
  • 大的对象会直接存储到老年代内存区域,小对象会直接存储到新生代内存区域,每次 GC 一次存活下来后就存活时间 +1,当达到 15 的时候,就把这个小对象移到老年代内存区域。
9、Android 四大引用解析?
  • 强引用(StrongReference):不会被回收,只有 JVM 停止的时候才会终止。
  • 软引用(SoftReference):GC 时并且内存临近阀值或不足的时候,才会被回收。
  • 弱引用(WeakReference):GC 时不管内存是否充足,都会被回收。
  • 虚引用(PhantomReference):随机于 GC 的回收。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值