Excption与Error包结构。OOM你遇到过哪些情况,SOF你遇到过哪些情况

Java语言把异常当做对象来处理,并定义了一个基类(java.util.Throwable)作为所有异常的父类。异常分为Error和Exception两大类。

  • Error

        不可恢复的异常

        程序中不推荐去捕获Error类型的异常,主要原因是:运行时异常多是由于逻辑错误导致的,属于应该解决的错误。也就是说,一个正确的程序中是不应该存在Error的。当这些异常发生时,JVM一般会选择将线程终止。

  • Exception

        可恢复的异常

        (1) 检查异常

              所有继承Exception并且不是运行时异常的异常都是检查异常。

              这种异常发生在编译阶段,Java编译器强制程序去捕获此类异常。

        (2) 运行时异常

             编译器没有强制对其进行捕获并处理。当出现这种异常时,会由JVM来处理,eg. NullPointerException、ClassCastException、ArrayIndexOutOfBoundsException,ArithmeticException等。

             出现运行时异常后,系统会把异常一直往上层抛出,直到遇到处理代码为止。若没有处理块,则跑到最上层。

             如果不对运行时的异常进行处理,后果是非常严重的,一旦发生,要么是线程中止,要么是主程序终止。

       

在使用异常处理时,要注意以下几个问题:

        (1) 先捕获子类,再捕获基类的异常信息。

        (2) 尽早抛出异常。

        (3) 异常能处理就处理,不能处理就抛出。

        (4) 可以根据实际的需求自定义异常类,只要继承自Exception类即可。


  • OOM(OutOfMemoryError)        

        除了PC外,其他几个运行时区域都有发生OOM异常的可能性。

        (1) Java堆

              如果堆中没有内存完成实例分配,且堆无法扩展,抛出OOM。

        (2) Java栈和本地方法栈

              若线程请求的栈深度大于虚拟机所允许的最大深度,将抛出SOF;

              如虚拟机在扩展栈时,仍无法申请到足够的内存空间,则抛出OOM。

        (3) 方法区

              如果方法区无法满足内存分配需求时,将抛出OOM。

        (4) 运行时常量池

              如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法。该方法的作用是:如果池中已经包含一个等于此String的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。由于常量池分配在方法区内,我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制其中常量池的容量。

  • SOF(StackOverFlowError)

         程序中一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过默认大小而导致溢出。

         栈溢出的原因

              (1) 递归调用

              (2) 大量循环或死循环

              (3) 全局变量是否过多

              (4) 数组、List、Map数据过多

原文地址:https://www.cnblogs.com/jiqianqian/p/6561721.html