当前位置: 首页 > article >正文

关于Error和Exception的一些思考 小结

目录

1. ERROR

2. Exception

2.1 checked Exception

2.2 unchecked Exception

2.3 区别

3. 内存溢出

3.1 堆溢出

3.2 永久代/元空间溢出

3.3 方法栈溢出


Java中,所有的异常都有一个共同的父类:Throwable类。

Throwable类有两个重要的子类:Exception(异常)和Error(错误)。

Exception和Error二者都是Java异常处理的重要子类,各自都包含大量子类,只有Throwable类型的实例才可以被抛出(throw)或捕获(catch)。

1. ERROR

Error属于程序无法处理的错误,是JVM需要负担的责任,无法通过try-catch来进行捕获。

例如,系统崩溃,内存不足,堆栈溢出等,编译器不会对这类错误进行检测,一旦这类错误发生,通常应用程序会被终止,仅靠应用程序本身无法恢复。

如:StackOverFlowError;VirtualMachineError;OutofMemoryError;ThreadDeath。

2. Exception

程序本身可以处理的异常,可以通过catch来进行捕获,通常遇到这种错误,应对其进行处理,使应用程序可以继续正常运行。

Exception又可以分为运行时异常(RuntimeException,又叫非受检查异常unchecked Exception)和非运行时异常(又叫受检查异常checked Exception)。

2.1 checked Exception

在写代码的时候,需要写try catch的Exception,这种Exception一般不会影响主体程序,可以由程序员手动诊断修复异常。

如:IOException;SQLException;ClassNotFoundException。

2.2 unchecked Exception

又称RunTimeException,这一类就是在代码处理了checked Exception之后,运行时候仍然会遇到的Exception。

如:NullPropagationException;ClassCastException;ArithmeticException;IllegalArgumentException;IndexOutOfBoundsException(包括ArrayIndexOutofBoundsExcpetion;StringIndexOutofBoundsExcpetion);NumberFormatException。

2.3 区别

1) Checked Exception 的基类是 Exception,Runtime Exception 的基类是 RuntimeExceptionRuntimeException 的父类也是 Exception)。

2) Checked Exception 要求必须捕获,一个方法内如果抛出了 Checked Exception,必须要么 catch,要么给方法声明 throws 以交给上一层去处理,如果漏写了 catch 会直接通不过编译。 Runtime Exception 就没这个要求,不强制 catchthrows,这样对于明显不会异常的代码段就不必处理了。

3. 内存溢出

3.1 堆溢出

java.lang.OutOfMemoryError: Java heap space

1) 原因。

  • 代码中可能存在大对象分配。
  • 可能存在内存泄露,导致在多次GC之后,还是无法找到一块足够大的内存容纳当前对象。

2) 解决方法。

  • 检查是否存在大对象的分配,最有可能的是大数组分配。
  • 通过jmap命令把堆内存保存下来,使用mat工具分析检查是否存在内存泄露的问题。
  • 如果没有找到明显的内存泄露,使用 -Xmx 加大堆内存。
  • 检查是否有大量的自定义的 Finalizable 对象,也有可能是框架内部提供的,考虑其存在的必要性。

3.2 永久代/元空间溢出

java.lang.OutOfMemoryError: PermGen spacejava.lang.OutOfMemoryError: Metaspace

1) 原因。永久代是 HotSot 虚拟机对方法区的具体实现,存放了被虚拟机加载的类信息、常量、静态变量、JIT编译后的代码等。JDK8后,元空间替换了永久代,元空间使用的是本地内存,字符串常量由永久代转移到堆中,可能原因有如下几种:

  • 在Java7之前,频繁的错误使用String.intern()方法。
  • 运行期间生成了大量的代理类,导致方法区被撑爆,无法卸载。
  • 应用长时间运行,调试时没有重启 JVM。

2) 解决方法。

  • 检查是否永久代空间或者元空间设置的过小。
  • 检查代码中是否存在大量的反射操作。
  • 通过mat检查是否存在大量由于反射生成的代理类。
  • 重启JVM。

3.3 方法栈溢出

java.lang.OutOfMemoryError : unable to create new native Thread

1) 原因。

  • 出现这种异常,基本上都是创建了大量线程导致的。

2) 解决方法。

  • 通过 -Xss 降低的每个线程栈大小的容量。
  • 线程总数也受到系统空闲内存和操作系统的限制,检查是否该系统下有此限制:/proc/sys/kernel/pid_max/proc/sys/kernel/thread-maxmaxuserprocess(ulimit -u)/proc/sys/vm/maxmapcount

http://www.kler.cn/a/4145.html

相关文章:

  • 利用摄影测量进行地形建模的介绍
  • Linux产生死锁的必要条件和常见的锁种类
  • uniapp - APP云打包、蒲公英平台发布APP的步骤
  • 上海亚商投顾:创业板指低开高走ChatGPT概念股再爆发
  • 一文快速回顾 Java 操作数据库的方式-JDBC
  • 给你一个购物车模块,你会如何设计测试用例?【测试用例设计】
  • 【云原生】初识 Kubernetes — pod 的前世今生
  • centos7配置pytorch和tensorflow
  • 猿创征文 | re:Invent 朝圣之路:“云“行业风向标
  • 【敏捷开发】jenkins「CI持续集成 CD持续部署」
  • 基于 OpenCV 与 Java 两个语言版本实现获取某一图片特定区域的颜色对比度
  • 从GPT-4、文心一言再到Copilot,AIGC卷出新赛道?
  • Kafka在Mac下的安装与使用
  • 多级评论单表结构设计
  • Maven和Eclipse联合开发
  • js 数据类型
  • 如何将pdf大小压缩?怎么缩小pdf的文件大小?
  • 关于微信小程序安装npm的过程,从下载到小程序内部安装完成
  • gitignore文件的作用和语法
  • 设置鼠标右键打开方式,添加IDEA的打开方式