目录
- 一、ch 2 exception和error
- 二、ch4| 强引用、软引用、弱引用、幻象引用
一、ch 2 exception和error
1、知识概要
- 理解 Java 语言中操作 Throwable 的元素和实践。掌握最基本的语法是必须的,如 try-catch-finally 块,throw、throws 关键字等。
- 生吞异常(捕获异常最差的处理方式)
- 自定义异常:定义成checked exception
(但:①大多数情况并不能恢复程序②不兼容functional编程)
,并避免包含敏感信息
2、案例分析
- 输入以下代码
public class test {
public static void main(String[] args) {
try {
Class.forName("src.HelloWorld");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public class test {
public static void main(String[] args) {
try {
Class.forName("tsst321.HelloWorld");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
结果说明能成功运行
3、问题提出与解决
- 问题一:NoClassDefFoundError 和 ClassNotFoundException 有什么区别?
- 问题一解决:
NoClassDefFoundError是一个错误(Error),而ClassNOtFoundException是一个异常,在Java中错误和异常是有区别的,我们可以从异常中恢复程序但却不应该尝试从错误中恢复程序。
加载时从外存储器找不到需要的class就出现ClassNotFoundException
连接时从内存找不到需要的class就出现NoClassDefFoundError
- classnotfoundexception发生在装入阶段
- 如果这个类在类路径中没有被找到——确保所需的类连同它依赖的包存在于类路径中
- 当一个类已经某个类加载器加载到内存中了,此时另一个类加载器又尝试着动态地从同一个包中加载这个类——选择catch这个衣长然后采取补救措施
- NoClassDefFoundError: 发生在运行阶段。(当目前执行的类已经编译,但是找不到它的定义时,编译时能找到,但是运行时找不到)
4、参考资料
- 第2讲 | Exception和Error有什么区别?
- java.lang.ClassNotFoundException与java.lang.NoClassDefFoundError的区别 -xingoo - 博客园
ch4 强引用、软引用、弱引用、幻象引用
1、内容概要
① 强引用(在程序代码中普遍存在的)
- 特点:
Object obj = new Object()
中的obj
就是强引用;通过关键字new
创建的对象所关联的引用就是强引用。 - 当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),使程序异常终止,也不会靠随意回收具有强引用的“存活”对象来解决内存不足的问题。
② 软引用(描述一些有用但并不是必需的对象)
- 特点:通过
SoftReference
类实现,在Java中用java.lang.ref.SoftReference
来表示。 软引用的生命周期比强引用短一些。 - JVM 会确保在抛出 OutOfMemoryError 之前,清理软引用指向的对象。
- 应用场景:软引用通常用来实现内存敏感的缓存。如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。
③ 弱引用(描述非必需对象)
- 特点:通过
WeakReference
类实现,在java中,用·java.lang.ref.WeakReference·类来表示。弱引用的生命周期比软引用短。 - 一旦发现了具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。
- 应用场景:弱应用同样可用于内存敏感的缓存。
④ 幻想引用
- 特点:虚引用也叫幻象引用,通过
PhantomReference
类来实现,在java中用java.lang.ref.PhantomReference
类表示无法通过虚引用访问对象的任何属性或函数。 - 虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。
ReferenceQueue queue = new ReferenceQueue ();
PhantomReference pr = new PhantomReference (object, queue);
程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。
- 应用场景:可用来跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知。
2、示例
- 软引用
import java.lang.ref.SoftReference;
public class reference {
public static void main(String[] args) {
SoftReference sr = new SoftReference(new String("hello"));
System.out.println(sr.get());
}
}
- 弱引用
import java.lang.ref.WeakReference;
public class reference {
public static void main(String[] args) {
WeakReference sr = new WeakReference(new String("hello"));
System.out.println(sr.get());
System.gc(); //通知JVM的gc进行垃圾回收
System.out.println(sr.get());
}
}
- 虚引用
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class reference {
public static void main(String[] args) {
ReferenceQueue queue = new ReferenceQueue();
PhantomReference pr = new PhantomReference(new String("hello"), queue);
System.out.println(pr.get());
}
}
3、问题提出与解决
- 问题一:什么是可达性?
- 问题一解决:可达性分析其实是用来判定对象是否存活的。如果不可达,则证明该对象不可用,说明其可以被回收。
- 问题二:如何判断是否需要被回收?
- 问题二解决:
Strong Reference : 只有在引用对象root不可达的情况下才会标识为可回收,垃圾回收才可能进行回收
Soft Reference : 无论其引用的对象是否root可达,在响应内存需要时,由垃圾回收判断是否需要回收。
Weak Reference :用来描述非必需对象。即使在root算法中 其引用的对象root可达到,只能生存到下一次垃圾回收之前。
Phantom Reference :无法通过虚引用获得一个对象的实例,设置虚引用的目的就是能在这个对象被收集器回收时收到一个系统通知。
- 问题三:除了可达性算法,还有什么方法来判断对象是否存活?
- 问题三解决:finalize()方法
- 进行两次标记
- 只要重新与引用链上的任何的一个对象建立关联,譬如把自己赋值给某个类变量或对象的成员变量,那在第二次标记时它将移除出“即将回收”的集合。
4、参考资料
- java 垃圾回收总结(可达性分析 引用分类
- 第4讲 | 强引用、软引用、弱引用、幻象引用有什么区别?
- 可达性算法、Java引用 详解 - 简书