先看一个图

一个程序在这个体系中的执行过程
当一个程序被运行起来时,os会将他加载(load)进内存,也就是一个进程,这个cpu和内存会一起为这个进程而服务,进程中将会有指令和数据,cpu就会并发的去执行内存里进程的指令或者读取数据,而进程中由具体分作好多线程,于是就由程序的栈和堆的概念。
所谓的栈就是线程栈,每个线程一个栈,这个栈中就是该线程执行的方法的地方,每一个方法在栈中又叫栈帧,每一个方法就是一个栈帧,so,不难理解,方法的调用其实就是栈顶指针上下移动的一个过程。
而在方法中将会产生好多变量,其实就是内存中的一块空间,变量存放的地方称之为堆空间,程序在执行时,动态规划的空间,就是堆,而程序中的变量其实就是指向堆中的某一个位置的地址。
区别
不难看出,作为栈空间,内存将会被自动的释放,方法执行完毕,栈顶指针下移,该栈帧的空间就被释放了。
但是,作为堆空间,是被手动new出来的,方法虽然结束了,但是实际上该内存空间是出于一个被占用的情况。
而事实上,这也是程序之中最难被调试的bug来源。
涉及到两个具体的程序问题就是
- 野指针
- 并发线程
说白了就是一个堆空间中的内存,能且只能被释放一次,当程序方法结束之后,没有正确的释放占用的内存,是bug,释放之后却还能释放也是bug。
扩展思考
c/c++:需要程序员编程时,思考内存释放的问题
而像
java/python/go等:就引入了GC,也即是垃圾回收机制,程序员编写时,不需要考虑内存释放问题。有一个线程会随着应用程序一起跑,负责回收释放内存空间。
所以说,前者运行效率很高,但是开发周期和维护成本也高,而后者开发效率很低,但是运行起来效率就没有那么高了,但是现在硬件的成本明显要比时间成本低得多。
本文探讨了程序执行中栈与堆的作用,如何影响线程、变量和内存释放,重点讲解了野指针与并发线程引发的bug,并对比了C/C++与Java/Python等编程语言在内存管理上的异同。
2270

被折叠的 条评论
为什么被折叠?



