面经2

四种引用

强引用

一个对象具有强引用,它就不会被垃圾回收器回收,即使当前内存空间不足,JVM也不会回收它,而是抛出OutOfMemoryError错误,使程序终止。如果想中断强引用和某个对象之间的关联,可以显式的引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。

String str = "hello"; //强引用
str = null//取消强引用

软引用

在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收;只有在内存空间不足时,软引用才会被垃圾回收器回收。

SoftReference<String> softName = new SoftrReference<>("张三");

弱引用

具有弱引用的对象拥有的生命周期更短暂。因为当JVM进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以不一定能徐苏发现弱引用对象。

WeakReference<String> weakName = new WeakReference<String>("hello");

虚引用

形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。

虚引用必须和引用队列关联使用,当垃圾回收器逐准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之关联的引用队列中,程序可以通过判断引用队列中是否已经加入了虚引用,来了解引用对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要行动。

ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<Strring> pr = new PhantomReference<String>(new String("hello"),queue);

 

垃圾回收的四种算法,具体应用场景

GC的三件事

java虚拟机如何判断一个对象是可以回收的

那些内存可以回收(引用计数算法和可达性分析算法):

引用计数算法:

给对象添加一个引用计数器,每当有一个地方引用它时,计数器值加1;

当引用失效时,计数器减1;

任何时刻计数器为0的对象就是不可能再被使用的;

(优点)实现简单,判定效率高

(缺点)很难解决对象之间循环引用的问题。主流的虚拟机里没有选用引用计数算法来管理内存。例如objectA = objectB,objectB = objectA,两个相互引用对法,导致引用计数都不为0,于是引用计数算法无法通知GC收集器回收它们。

可达性分析算法:

通过一系列的成为GC Roots的对象作为起始点,从这些节点开始往下搜索,搜索所有走过的路径称为引用链,再从一个每个引用对象,从一个对象到GCRoots没有任何引用链相连时,则证明此对象是不可用的。

 

 当一个对象到GC Roots的引用链不可达时,则被判定为是可回收对象。

Java语言中,可以作为GC Roots的对象包括

①虚拟机栈(栈帧中的本地变量表)中引用的对象。

②方法区中静态属性引用的对象。

③方法区中常量引用的对象,在jdk7后被移到堆中。

④本地方法栈中JNI(即一般说的Native方法)引用的对象。

(优点)更加精确严谨,可以分析出循环数据结构相互引用的情况。

(缺点)实现比较复杂;需要分析大量数据,小号大量时间;分析过程需要GC停顿(引用关系不能发生变化),即停顿所有Java执行线程(称为“Stop The World”,垃圾回收重点关注的问题);

什么时候回收(堆的新生代、老年代、永久代的垃圾回收时机,MinorGC和FullGC):

在做可达性分析算法时,不可达的对象是已经可以被GC的,但是实际上其实这个对象并非是立即就要被GC,真正清理一个对象,至少要经历两次标记过程

第一次标记

如果对象在进行可达性分析后发现没有与GCRoots相连接的引用链,将被做第一次标记并进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都当做没有必要执行。

当这个对象的finalize有必要执行(尚且有一线生机),这个对象将被放置在一个F-Queue的队列中,并稍后由一个虚拟机自动建立的、低优先级的Finalizer线程去触发这个方法。

第二次标记

GC将对F-Queue队列汇总的对象进行第二次小规模标记;finalize()方法时对象逃脱死亡的最后一次机会:如果对象在其finalize()方法中重新与引用链上任何一个对象建立关联,第二次标记时将其移出“即将回收”的集合;如果对象没有。也可以认为对象已死,可以回收了;一个对象的finalize()方法只会被系统自动调用一次,英国finalize()方法逃脱死亡的对象,第二次不会再调用。

## 如何回收(经典垃圾回收算法(标记清除算法、赋值算法、标记整理算法)收集算法和其中垃圾收集器)

erro与Exception

 

 三种类型的异常

检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。

运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时可以在编译过程忽略是可以预见的甚至是程序员自己写的异常。

错误:错误不是异常,而是脱离程序员控制的问题。可能是JVM内存溢出这类不是代码上的问题。

Throwable分成两类分支

Error类,表示不希望被程序补获不欧哲是程序无法处理的错误。

虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。例如,Java虚拟机运行错误(Virtual
MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现
OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止;还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之
外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在Java中,错误通常是使用Error的子类描述。

Exception类,镖师用户程序可能补获的异常情况或者说是程序可以处理的异常。(还可以分为运行时异常与非运行时异常)

Exception:在Exception分支中有一个重要的子类RuntimeException(运行时异常),该类型的异常自动为你所编写的程序定义ArrayIndexOutOfBoundsException(数组下标越界)、NullPointerException(空指针异常)、ArithmeticException(算术异常)、MissingResourceException(丢失资源)、ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;而RuntimeException之外的异常我们统称为非运行时异常,类型上属于Exception类及其子类,从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

 

 

 

hashmap的数据结构,1.7与1.8的区别

(1)JDK1.7用的是头插法(插入在当前位置,当前位置的值后移),而JDK1.8以后使用的尾插(在当前节点后端插入)法,1.7用单向链表纵向眼神,当采用头插法时会容易出现逆序且环形链表死循环问题。但是再JDK1.8以后是因为加入红黑树使用尾插法,能够避免出现逆序且链表死循环的问题。

(2)扩容后数据存储位置的计算方式不一样,JDK1.7时是直接用hash值和需要扩容的二进制数进行&(这里就是因为扩容的时候为啥一定必须是2的多少次幂的原因所在,因为如果只有2的n次幂的情况时最后一位二进制数一定是1,这样能最大程度减少hash碰撞)

(3)在JDK1.7的时候是先扩容后插入的,这样就会导致无论这一次插入是不是发生hash冲突都需要进行扩容,如果这次插入的明没有发生Hash冲突的话,那么就会造成一次无效的扩容,但是再1.8的时候是先插入再扩容的,优点其实是因为为了减少这一次无效的扩容,原因就是如果这次插入没有发生Hash冲突的话,那么其实就不会造成扩容,但是在1.7的时候救护造成扩容。

(4)而在JDK1.8的时候直接用了JDK1.7的时候计算的规律,也就是扩容前的原始位置+扩容的大小值=JDK1.8的计算方式,而不再是JDK1.7的那种异或的方法。但是这种方式就相当于只需要判断Hash值的新增参与运算的还是0还是1就直接迅速计算出了扩容后的存储方式。

 

什么是泛型

 就是一种不确定的数据类型,比如ArrayList<E>其中E就是泛型。这总不确定的数据类型需要在使用这个类的时候才能够确定出来,泛型可以省略,如果省略默认泛型是Object,作用就是通过参数化类型来实现同一份代码上操作多种数据类型。省略了强转的代码。可以把运行时的问题提前到编译时期。

 

写两个线程

 

posted @ 2021-09-01 14:38  K峰  Views(27)  Comments(0Edit  收藏  举报