目录
面试题3.66 简单的介绍⼀下强引用,软引用,弱引用,虚引用
面试题3.62 JAVA中Object类中有哪些常用方法?
【技术难度:2 出现频率:1 】
第一层:
1.getClass()获取类的class对象;
2.hashCode()获取对象的hashCode值,子类可重写以自定义;
3.equals()比较对象是否相等,默认用==比较两个对象的内存地址,子类可重写以自定义;
4.clone()克隆方法,子类可重写以自定义,深克隆需要手动深度克隆对象中的目标内容;
5.toString()返回对象16进制的内存地址的哈希值以及类名等信息,子类可重写以自定义;
6.notify()随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态;
7.notifyAll()解除所有在该对象上调用wait方法的线程的阻塞状态;
8.wait()导致当前线程进入等待状态,直到他被其他线程通过notify()或者notifyAll()唤醒;
9.finalize()对象被GC回收时调用,只调用一次。
拓展:
- wait():当一个线程调用某个对象的wait()方法时,该线程会释放该对象的锁并进入等待状态,直到其他线程调用该对象的notify()或notifyAll()方法。
调用wait()的线程必须首先获得该对象的锁(即,它必须在同步代码块或同步方法中)。
wait()方法可以被重载,允许指定一个超时时间,在超时后线程会自动从等待状态返回。- notify():notify()方法用于唤醒正在等待该对象锁的单个线程。
如果有多个线程在等待,选择哪一个线程被唤醒是随机的,或者说是不可预测的。
被唤醒的线程将尝试重新获得唤醒对象手中的锁。- notifyAll():notifyAll()方法用于唤醒正在等待该对象锁的所有线程。
所有被唤醒的线程将竞争该对象的锁,其中一个线程将获得锁并继续执行,而其他线程将继续等待。
第二层:
notify()、notifyAll()、wait()方法只能在同步方法或同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。
面试题3.63 什么是深拷贝和浅拷贝
【技术难度: 2 出现频率:1 】
1.深拷贝和浅拷贝是针对对象和数组这样的引用类型,包装类和String类对象的值是不可变的,无需拷贝;
2.浅拷贝只克隆当前对象本身,而不克隆它成员变量指向的对象,新旧对象的成员变量还是指向堆中相同数据;
3.深拷贝会深度克隆对象中所有内容,修改新对象不会影响原对象。
扩展(无需背诵):
面试题3.64 GC是什么? 为什么要有GC?
【技术难度:3 出现频率:2 】
GC是垃圾收集的意思,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显式操作方法。
扩展(无需背诵):
GC - Gabage Collection 垃圾收集。
内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃。
面试题3.65 JVM垃圾回收机制和常见算法
【技术难度:3 出现频率:2 】
第一层:
理论上来讲Sun公司只定义了垃圾回收机制规则而不局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同。GC在回收对象前首先必须发现那些无用的对象,此时会通过搜索算法去发现定位这些无用的对象。搜索到无用对象之后就是回收过程,再通过回收算法进行回收。
垃圾算法的实现涉及大量的程序细节,而且不同的虚拟机平台实现的方法也各不相同。
第二层:
常用的搜索算法有这些:
1)引用计数器算法(废弃)
引用计数器算法是给每个对象设置一个计数器,当有地方引用这个对象的时候,计数器+1,当引用失效的时候,计数器-1,当计数器为 0 的时候,JVM 就认为对象不再被使用,是“垃圾”了。引用计数器实现简单,效率高;但是不能解决循环引用问问题(A 对象引用 B 对象,B 对象又引用 A 对象,但是A,B对象已不被任何其他对象引用),同时每次计数器的增加和减少都带来了很多额外的开销,所以在 JDK1.1 之后,这个算法已经不再使用了。
2)根搜索算法(使用中)
根搜索算法是通过一些“GC Roots”对象作为起点,从这些节点开始往下搜索,搜索通过的路径成为引用链(Reference Chain),当一个对象没有被 GC Roots 的引用链连接的时候,说明这个对象是不可用的。
GC Roots 对象包括:
a) 虚拟机栈(栈帧中的本地变量表)中的引用的对象。
b) 方法区域中的类静态属性引用的对象。
c) 方法区域中常量引用的对象。
d) 本地方法栈中 JNI(Native 方法)的引用的对象。
第三层:
常用的回收算法如下: