关于异常

虽然这次的主题是异常,但是说的更确切点应该叫程序是如何运行的。

编程语言是在计算机的内存中运行起来的,然而运行的时候,无论是基于jvm的java、scala之类的语言,还是像C/C++这样直接跟操作系统打交道的语言,都会将得到的内存分为几个区域,每个区域负责不同的事情。

大体上程序内存被分为这样的几个区域:

堆(heap):malloc、new 这样的关键字生成的对象都会利用这个区间的内存;当然jvm中堆会被进一步的细分为老年代、新生代,新生代又有伊甸园、幸存者,这个以后有时间专门介绍;

栈(stack):这块主要是给线程使用的,当线程调用一个方法的时候,就会有一个栈帧(frame)入栈,正常情况下方法执行结束,对应的frame出栈,再调用的新的frame入栈;

方法区:差不多就是程序员写的代码被编译成机器码之后就会存放在这里了,hotspot在java8中已经弃用方法区改为metastore,主要的区别好像就是gc变得容易了。

当然还有其他很多区域,这里就不一一介绍了,以上几个区域的关系大概如下图

下面回归正题介绍异常:

异常的大概形式大家应该都很熟了,try、catch、finally在加上不太常用的throw、throws,这里就不介绍了。大概差不多是像下面这么使用的:

来分析一下发生异常的时候执行method2的线程的栈的使用情况:

1.首先method2对应的栈帧(frame2)入栈;

2.执行method1即method1对应的栈帧(frame1)入栈;

3.如果method1成功执行,则frame1出栈,接着method2执行成功,method2对应的frame2出栈,线程结束;如果method1抛出异常,首先构建异常对象e,frame1出栈,接着找当前上下文有没有对应的处理异常的语句(即执行method1的时候有没有对应的exception的catch语句),发现没有,所以到上一层即method2的上下文中查找,发现刚好有;

4.catch对应的代码块其实也可以看成一个参数是异常e的引用的方法了(就像public void catch(Execption e)),对应的catch frame入栈,执行e.printStackTrace()。

根据上面的分析,可以看出,如果不会发生异常,即使写了try、catch对程序的效率应该也没有影响;发生异常最大的影响在于要构造对应的异常对象,并且要不断地向上回归找取处理异常的catch方法。

现在假设有这么一个场景,需要做两个整数的减法,假设我们现在还是小学生不知道什么叫做负数,那么当被减数小于减数的时候,我们就不知道该怎么处理了,这就是一种异常了,所以定义如下异常。

接着定义了两个处理减法操作的方法,一个用作对比不抛出异常(method1),一个是我们观察的重点要抛出异常(method2):

在以下四种场景下调用1000次减法操作:

1.调用1000次的method1,这个时候根本没有异常;

2.在保证被减数更大的情况下调用1000次method2,这个时候不会抛出异常;

3.在保证被减数更小的情况下调用1000次method2,这个时候一定抛出异常;

4.在保证被减数更小的情况下调用1000次method2,而调用method2的函数不直接处理异常(没有对应的catch块),这个时候一定抛出异常而且按道理会比第三种情况要慢;

以下是十次试验之后的结果对比:

虽然实验次数不太多,但是结果还是比较明显的,在没有真正发生异常的时候,程序效率不会明显下降;但是如果真的发生了异常对异常的处理带来了额外的开销,而且捕捉的越不及时开销越大。

相关代码已经打包上传,欢迎大家指处不足。

2017.2.5

明天要上班 /(ㄒoㄒ)/~~

时间: 2024-11-11 22:18:42

关于异常的相关文章

使用 IDEA 创建 Maven Web 项目 (异常)- Disconnected from the target VM, address: '127.0.0.1:59770', transport: 'socket'

运行环境: JDK 版本:1.8 Maven 版本:apache-maven-3.3.3 IDEA 版本:14 maven-jetty-plugin 配置: <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <webAppSourceDirectory>${pro

mybaits非配置原因,导致SqlSession was not registered for synchronization异常

今天运行程序时报了 SqlSession [[email protected]] was not registered for synchronization because synchronization is not active [11:03:17]-Closing non transactional SqlSession [[email protected]] 由于异常是集中处理的,所以报了这样的错误,查了半天,网上结果都是说配置文件出错的,可是我的项目配置文件肯定是没错的,因为项目都开

异常笔记--java编程思想

开一个新的系列,主要记一些琐碎的重要的知识点,把书读薄才是目的...特点: 代码少,概念多... 1. 基本概念 异常是在当前环境下无法获得必要的信息来解决这个问题,所以就需要从当前环境跳出,就是抛出异常.抛出异常后发生的几件事: 1.在堆上创建异常对象. 2.当前的执行路径中止                                          3. 当前环境抛出异常对象的引用.                                         4. 异常处理机制接

爱上MVC~业务层刻意抛出异常,全局异常的捕获它并按格式返回

对于业务层的程序的致命错误,我们一直的做法就是直接抛出指定的异常,让程序去终断,这种做法是对的,因为如果一个业务出现了致命的阻塞的问题,就没有必要再向上一层一层的返回了,但这时有个问题,直接抛异常,意味着服务器直接500了,前端如何去显示,或者如果你是API的服务,如果为前端返回,如果是500,那直接就挂了,哈哈! 下面是在MVC环境下优化的全局异常捕获代码(非API) /// <summary> /// 全局异常捕获 /// </summary> public class Glo

Laravel 5.4 中的异常处理器和HTTP异常处理实例教程

错误和异常是处理程序开发中不可回避的议题,在本地开发中我们往往希望能捕获程序抛出的异常并将其显示打印出来,以便直观的知道程序在哪里出了问题并予以解决,而在线上环境我们不希望将程序错误或异常显示在浏览器中(出于安全考虑),这个时候我们仍然要捕获异常,只不过不是显示到浏览器中,而是记录到日志中,方便日后排查问题. 百牛信息技术bainiu.ltd整理发布于博客园 Laravel当然支持PHP原生的错误和异常处理,但是在此基础上进行了一些封装处理,从而更方便在不同开发环境切换以及对错误和异常的处理.

Java必知必会:异常机制详解

一.Java异常概述 在Java中,所有的事件都能由类描述,Java中的异常就是由java.lang包下的异常类描述的. 1.Throwable(可抛出):异常类的最终父类,它有两个子类,Error与Exception. Throwable中常用方法有: getCause():返回抛出异常的原因.如果 cause 不存在或未知,则返回 null. getMeage():返回异常的消息信息. printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值.

python 异常和弹出框

import tkinter.messagebox try: fileContent = open("abnormal.txt") fileContent.close() print("over") #把异常消息赋予一个"ex"变量 except Exception as ex: print(ex) tkinter.messagebox.showinfo("Alert",ex) tkinter.messagebox.askye

python基础--接口与归一化设计、封装、异常、网络编程

1 接口与归一化设计 1.1 归一化概念: 归一化的好处: 1.归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大降低了使用者的使用难度. 2.归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合 继承的两种用途 一:继承基类的方法,并且做出自己改变或者扩展(代码重用):实践中,继承的这种用途意义并不很大,甚至常常是有害的.因为它使得子类与基类出现强耦合. 二:声明某个子类兼容于某基类,定义一个接口类(模仿java的Interface),接口类中

异常上报工具:腾讯Bugly

1.腾讯出了一个和umeng差不多的异常上报工具Bugly.(传送门:https://bugly.qq.com/docs/) (1)两者比较明显的区别是,Bugly能比较实时上报异常信息,经过测试基本上几秒就能在后台看到上报的信息,umeng的要等一段时间:(这个是我选择Bugly的主要原因) (2)Bugly感觉比较轻盈,主要方向就是异常上报:umeng感觉比较臃肿,主要方向在后台数据统计上:(个人感觉) 2.Cocos的接入文档就在里面,提供了c++/lua/js三种方式的接入,很简单方便就

最近遇到的异常与错误总结

异常 NumberFormatException  数字格式化异常 ArithmeticException 算术异常 ArrayIndexOutOfBoundsException  数组超出绑定异常:没有输入参数,或输入的参数不够 NullPointerException 空指针异常:使用了未实例化的对象 NoSuchMethodError:main  找不到主方法 ClassCastExeption:A 类转换异常 IllegalThreadStateException:非法的线程状态异常 I