JVM 面试 - JiyangM/spring GitHub Wiki
https://www.cnblogs.com/wmyskxz/p/9045972.html
https://www.jianshu.com/p/54eb60cfa7bd
Java 虚拟机是如何判定两个 Java 类是相同的?
Java 虚拟机是如何判定两个 Java 类是相同的。Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。只有两者都相同的情况,才认为两个类是相同的。即便是同样的字节代码,被不同的类加载器加载之后所得到的类,也是不同的。比如一个 Java 类
public void testClassIdentity() {
String classDataRootPath = "C:\\workspace\\Classloader\\classData";
FileSystemClassLoader fscl1 = new FileSystemClassLoader(classDataRootPath);
FileSystemClassLoader fscl2 = new FileSystemClassLoader(classDataRootPath);
String className = "com.example.Sample";
try {
Class<?> class1 = fscl1.loadClass(className);
Object obj1 = class1.newInstance();
Class<?> class2 = fscl2.loadClass(className);
Object obj2 = class2.newInstance();
Method setSampleMethod = class1.getMethod("setSample", java.lang.Object.class);
setSampleMethod.invoke(obj1, obj2);
} catch (Exception e) {
e.printStackTrace();
}
}
对象分配规则?
JVM指令重排序?
在执行程序时,为了提供性能,处理器和编译器常常会对指令进行重排序,但是不能随意重排序,不是你想怎么排序就怎么排序,它需要满足以下两个条件:
- 在单线程环境下不能改变程序运行的结果;
- 存在数据依赖关系的不允许重排序
重排序会产生问题,比如一个boolean类型的变量初始值是false,然后后面是一段业务逻辑,执行完后将boolean的值置为true,当指令重排序的时候可能会将业务顺序和变量赋值的顺序调整,这样的话就会有问题。
volatile 保证了原子可见性和顺序性,实现参见:
https://github.com/JiyangM/spring/wiki/volatile
内存屏障?
答:内存屏障,又称内存栅栏,是一组处理器指令,用于实现对内存操作的顺序限制。
类加载器是如何加载 class 文件的?
类似-Xms、-Xmn这些参数的含义:
堆内存分配:
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64
JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。
因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。 非堆内存分配:
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。 -Xmn2G:设置年轻代大小为2G。
-XX:SurvivorRatio,设置年轻代中Eden区与Survivor区的比值。
内存泄漏和内存溢出
概念:
- 内存溢出指的是内存不够用了。
- 内存泄漏是指对象可达,但是没用了。即本该被GC回收的对象并没有被回收
- 内存泄露是导致内存溢出的原因之一;内存泄露积累起来将导致内存溢出。
- 内存泄漏的原因分析:
内存泄漏的原因分析:
- 长生命周期的对象引用短生命周期的对象
- 没有将无用对象置为null
简述一下 Java 中创建一个对象的过程?
对象的内存布局是怎样的?
对象是如何定位访问的?
GC什么时候开始?
引用的分类?
垃圾收集器?
对象是如何定位访问的?
对象的访问定位有两种:句柄定位和直接指针。
这两种对象的访问方式各有优势,使用句柄访问方式的最大好处就是reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要被修改。
使用直接指针访问方式的最大好处就是速度更快,它节省了一次指针定位的的时间开销。