程序的运行与崩溃
软件被开发出来,存在磁盘里面的是一段段文本,这样的代码称之为程序。要想将程序运行起来,就必须交给CPU(中央处理单元)进行处理。而这样一个运行起来的程序就是进程。
进程不只包含可执行代码,还包括进程在运行期间使用的堆内存空间、栈空间、供操作系统管理用的数据结构。当代码被加载到CPU,并生成相应的数据结构和内存空间后,就从可执行代码的起始位置交由CPU顺序读取指令。
程序运行时如果需要创建对象或是其他数据结构,就会在堆内存中为其分配空间,然后将这个空间的地址记录到栈当中。函数的调用则是通过栈来实现,由于当前执行的函数永远处于栈顶,因此多个函数之间可以定义相同的变量名而不引起混乱。
一台计算机能够同时处理数以百计的任务得益于CPU分时共享技术。如果同时有多个任务在执行,操作系统会将CPU的执行时间分成很多份,进程按照某种策略轮流在CPU上执行。由于这个时间是非常短的,因此会造成一种所有进程同时运行的错觉。
不同进程轮流在CPU上执行,每次都要进行CPU的切换,这个过程代价是非常大的。实际上,每个用户请求对应的是一个线程而不是一个进程,线程在CPU上进行切换的代价相对就要小一些。
说到线程就必须提一下线程的安全性问题。所谓线程安全性就是两个或多个线程获得同一个对象并对其进行修改所引发的问题。为了解决这个问题,就要使用锁来锁住对象,防止在操作一个对象时被其他线程获取。
虽然锁解决了线程安全性问题,但是会引起线程阻塞。如果有很多线程在运行,就会造成线程排队无法执行的情况,系统响应速度就会变慢。被阻塞的线程越多,系统资源占据的就越多,而且还不能释放这些资源,当超过了系统资源的极限就会导致应用崩溃。