jvm面试常提的问题
1.JVM如何加载一个类的过程,双亲委派模型中有哪些方法
类加载过程:加载、验证(验证阶段作用是保证Class文件的字节流包含的信息符合JVM规范,不会给JVM造成危害)、准备(准备阶段为变量分配内存并设置类变量的初始化)、解析(解析过程是将常量池内的符号引用替换成直接引用)、初始化。
双亲委派模型中方法:双亲委派是指如果一个类收到了类加载的请求,不会自己先尝试加载,先找父类加载器去完成。当顶层启动类加载器表示无法加载这个类的时候,子类才会尝试自己去加载。当回到最开的发起者加载器还无法加载时,并不会向下找,而是抛出ClassNotFound异常。
方法:启动(Bootstrap)类加载器,标准扩展(Extension)类加载器,应用程序类加载器(Application ),上下文(Custom)类加载器。意义是防止内存中出现多份同样的字节码 。
2.GC算法(什么样的对象算是可回收对象,可达性分析),CMS收集器
jvm是如何判断一个对象已经变成了可回收的“垃圾”,一般是两个方法:引用记数法和根搜索算法。引用记数法没办法解决循环引用的问题,所以用根搜索。从一系列的”GC Roots“对象开始向下搜索,搜索走过的路径称为引用链。当一个对象到”GC Roots“之间没有引用链时,被称为引用不可达。引用不可到的对象被认为是可回收的对象。
几种垃圾收集器:1,Serial New/Serial Old(串行),2,Parrallel New (并行),3,Parrallel Scavenge,4,Parrallel Old,5,CMS(CMS收集器是一个以获得最短回收停顿时间为目标的收集器,它是一种并发收集器,采用的是Mark-sweep算法。),6,G1(是一款并行与并发收集器,并且可建立可预测的停顿时间模型,整体上是基于标记清理,局部采用复制)
3.JVM分为哪些区,每一个区干吗的?
1)方法区(method):被所有的线程共享。方法区包含所有的类信息和静态变量。
2)堆(heap):被所有的线程共享,存放对象实例以及数组,Java堆是GC的主要区域。
3)栈(stack):每个线程包含一个栈区,栈中保存一些局部变量等。
4)程序计数器:是当前线程执行的字节码的行指示器。
4.JVM新生代,老年代,持久代,都存储哪些东西?
持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。所有新生成的对象首先都是放在年轻代的,年老代中存放的都是一些生命周期较长的对象。
5.内存溢出和内存泄漏:
内存溢出:程序申请内存时,没有足够的内存,out of memory;内存泄漏值垃圾对象无法回收,可以使用memory analyzer工具查看泄漏。
6.进程与线程:
进程值运行中的程序(独立性,动态性,并发性),线程指进程中的顺序执行流。区别是:1.进程间不共享内存 2.创建进程进行资源分配的代价要大得多,所以多线程在高并发环境中效率高。
7.序列化与反序列化:
序列化指将java对象转化为字节序列,反序列化相反。主要是为了java线程间通讯,实现对象传递。只有实现了Serializable或Externalizable接口类对象才可被序列化。
8.64 位 JVM 中,int 的长度是多数?
Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位。意思就是说,在 32 位 和 64 位 的Java 虚拟机中,int 类型的长度是相同的。
9.Java 中 WeakReference 与 SoftReference的区别?
Java中一共有四种类型的引用。StrongReference、 SoftReference、 WeakReference 以及 PhantomReference。
StrongReference 是 Java 的默认引用实现, 它会尽可能长时间的存活于 JVM 内,当没有任何对象指向它时将会被GC回收
WeakReference,顾名思义, 是一个弱引用, 当所引用的对象在
JVM 内不再有强引用时, 将被GC回收
虽然 WeakReference 与 SoftReference 都有利于提高 GC 和 内存的效率,但是 WeakReference ,一旦失去最后一个强引用,就会被 GC 回收,而 SoftReference 会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证), 这一特性使得
SoftReference 非常适合缓存应用
10.解释 Java 堆空间及 GC?
当通过 Java 命令启动
Java 进程的时候,会为它分配内存。内存的一部分用于创建堆空间,当程序中创建对象的时候,就从对空间中分配内存。GC 是 JVM 内部的一个进程,回收无效对象的内存用于将来的分配。
11.Java 中堆和栈有什么区别?
JVM 中堆和栈属于不同的内存区域,使用目的也不同。栈常用于保存方法帧和局部变量,而对象总是在堆上分配。栈通常都比堆小,也不会在多个线程之间共享,而堆被整个 JVM 的所有线程共享。