spice and wolfspice and wolf Be the One you wanna Be

JVM基础面试题

对象创建流程

Student student = new Student();

new String(“xyz”)会创建几个对象

String s = new String("xyz");

在运行上述代码时,会按一下流程执行:

  1. JVM会判断字面量”xyz”在字符串常量池的stringtable中是否能找到对应的记。
    • 没有,则在字符串常量池中创建”xyz”字符串对象,并在stringtable中增加对应的键值对指向当前对象。
    • 有,则返回stringtable对应记录中的字符串对象引用。
  2. new String对象。new会在程序运行时根据已经加载的String类在堆中实例化一个String对象,而根据String类的构造函数,该String对象同样会引用字符串常量池中的字符串对象地址。

所以有两种可能结果:

  1. 如果字符串常量池中之前并没有对应字面量的字符串记录,则会创建两个对象,分别是”abc”字符串常量和String类实例对象。
  2. 如果字符串常量池中之前存在对应字面量的字符串,则只会创建一个对象,就是String类实例对象。

为什么要使用元空间来替换永久代?

  • 字符串存在永久代中,容易出现性能问题和永久代内存溢出。
  • 类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
  • 永久代会GC带来不必要的复杂度,并且回收效率低。
  • Oracle计划将HotSpot与JRockit合二为一。

双亲委派机制

java源文件到jvm中运行,需要经过编译和类加载两个过程,其中类加载需要类加载器的参与,JVM运行过程中会产生三个类加载器:

  • Bootstrap ClassLoader(启动类加载器)。加载$JAVA_HOME中 jre/lib/rt.jar jre/lib/resource.jar里所有的class或Xbootclassoath选项置顶的jar包。
  • Extension ClassLoader(扩展类加载器)。加载java平台中扩展功能的一些jar包,包括jre/ext/*.jar或 -Djava.ext.dirs执行目录下的jar包。
  • Application ClassLoadder(应用类加载器)。加载classpath中指定的jar包及Djava.class.path锁制定目录下的类和jar包。

双亲委派机制逻辑:

双亲委派机制的好处:

  • 安全性。
  • 避免重复加载。

JVM垃圾回收机制

JVM判断一个对象是否需要被垃圾回收的关键就是判断对象是否仍在被使用,没有被使用则可以被垃圾回收。有两种方法:

  1. 引用计数器。该方法会为每一个对象添加一个引用计数器,用来统计对象被引用的次数,当引用次数降为0时,对象就能被垃圾回收,如果引用次数大于0则不能被垃圾回收。
    • 优点。实现简单。
    • 缺点。需要额外的内存空间存储对象引用计数器。
    • 问题。存在对象循环引用但是两个对象已经使用完的情况,因为两个循环引用对象的引用次数一直大于0,所以都不会被回收,这就造成了内存泄漏。
  2. 可达性分析。该算法的基本思路就是将GC ROOT对象作为起点,向下搜索和GC root对象有直接或间接引用关系的对象,如果这些对象可达,就表示仍在使用,不能被垃圾回收,如果不可达则表示已经不需要使用了,就可以被垃圾回收。目前主流的垃圾回收方案都是采用可达性分析算法。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Press ESC to close