Java面试题之 JVM虚拟机

冯诺依曼计算机体系结构:
控制器、运算器、存储器、输入设备、输出设备五部分组成 (不包括寄存器)

Java内存区域(运行时数据区)
Java面试题之 JVM虚拟机
共享的:
方法区:类的共有属性。
JVM堆:对象、数组

隔离的:
本地方法栈:Natitve 方法
虚拟机栈:局部变量区和操作数栈

注:每一个线程都会生成PC寄存器和虚拟机栈。

1.反射机制:
第一步:获取Java中的反射类的字节码
a.Class.forName() b.类名.class c.this.getClass()

第二步:将字节码中的方法,变量,构造函数等映射成对应类的方法、变量、构造函数。

2.泛型机制:
1.通过泛型的擦除机制所有泛型类的类型参数在编译时会被擦除,所以虚拟机中没有泛型,只有普通类和普通方法。
2.创建对象时要尽可能指明类型,让编译器尽早做参数 检查
3.运行时可以借助反射机制获取泛型类的参数类型

3.动态代理机制:
1.静态代理通常只能代理一个类,动态代理是代理以个接口下的多个实现类
2.AOP编程基于动态代理来实现的,比如Spring框架。
利用实现反射机制中invoke(Object,参数)方法 达到动态代理

4.对象的访问定位的两种方式:
a.局部访问:可以理解为指针的指针,需要二次定位
b.指针访问

5.JVM垃圾回收机制和常见算法:
a.引用计数法:当引用数为0时,对象死亡
b.根搜索算法:根对象到某对象不可达时,对象死亡。
Java面试题之 JVM虚拟机
其中 5、6、7 与根对象不可达,即为死亡。
注:程序员对垃圾回收机制 只有建议权,没有控制权

6.垃圾回收的算法:
a.标记-清除算法:效率偏低
b.复制算法:效率高,但是占用2倍内存
c.标记-整理算法:效率偏低
d.分代收集算法:把Java堆分为新生代和老年代,根据年代将特征选择上述算法。
老年代通常使用:a、c
新年代通常使用:b
GC分为2个部分:
GC:收集新年代的区域
Full GC:收集 新年代和老年代的区域

7.Java垃圾回收器:
a.串行垃圾回收器:单线程 “牵一发动全身”
b.并行垃圾回收器:多线程
c.并发标记扫描垃圾回收器 CMS:利用多线程对需要回收的对象进行标记并回收。
d.G1垃圾回收器:对比较大的进行回收,可以先压缩再回收。

既然有 GC 机制,为什么还会有内存泄露的情况:
存在无用但可达的对象,比如Hibernate中的Session,如果不及时flush()或者close(0,可能引发内存泄露。

8.介绍强引用、软引用、弱引用、虚引用:
a.强引用: A a=new A() 只要引用a存在,垃圾回收器不会回收。
b.软引用:类似于缓存的方式,不影响垃圾回收,可以提升速度,节省内存。若对象被回收,
get()为null,此时可以重新new SoftReference
c.弱引用:用于监控对象是否被垃圾回收器回收 isEnQueued方法 WeakReference
d.虚引用:每次垃圾回收的时候都会被回收。主要用于对象是否已经从内存中删除。 通过IsEnQueued方法 PhantomReference

9.栈stack和堆heap的区别:
a.栈由系统自动分配
b.堆:需要程序员自己申请并指明大小

10类加载机制:
类加载器的任务就是根据一个类的全限定名来读取次类的二进制字节流到JVM转换成 java.lang,class类
类加载过程:加载、验证、准备、解析和初始化。

双亲委托模型(确保加载的唯一性):当类收到加载请求时,它首先不会尝试加载这个类,
而是把请求委托给父类加载器执行,每个类都是如此(如果还有父类继续上交),如果父
类加载不了,子类加载才会进行加载。

A a=new A() 调用顺序
先加载父类静态代码区->父类非静态代码区->父类构造方法->子类静态代码区->子类非静态代码区->子类构造方法

11.Optional类的解析
解决的问题:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法。我们要在判断这个
返回值是否为null的前提下,只有在非空的前提下才能将其作为其他方法的参数。
Optional.of():为非 null 的值创建一个 Optional
Optional.ofNullable():为指定的值创建一个 Optional,如果指定的值为 null,则返回一个空的 Optional。
Optional.isPresent(): 判断预期值是否存在
Optional.get(): 如果 Optional 有值则将其返回,否则抛出 NoSuchElementException。
……