分类:
2009-06-21 13:46:46
内存泄漏大家都知道这个名字,具体原理鲜有教科书说明。现在我结合一点理论知识阐明一下这个问题,大家有玉的尽管砸过来啊!
1,引发问题的时间?
显然不运行的程序是不可能使用内存的,内存泄漏一定发生在该程序运行时刻。
2,发生内存泄漏的对象?
内存泄漏发生在程序运行时刻,静态的程序是不可能发生内存泄漏的。所以,发生内存泄漏的只可能是进程或者线程。而我们知道,操作系统内分配资源的基本单位是进程,线程之间是共享计算资源的。据此,发生内存泄漏的对象是进程。
3,引发内存泄漏的进程关闭后,那块内存泄漏区域是否可以被操作系统回收?
操作系统每次给一个进程分配内存页page,都会在相应的进程描述表里做记录,进程停止运行时,操作系统会回收所以分配给它的内存。要知道,当初操作系统分配内存的时候可不晓得提出申请的进程会泄漏内存,反正是分页的,每次也就4K(32bit系统),爱咋用咋用。进程死后还得全部归还。
因此,不管进程干了多少泄漏内存的事,只要它停止了,问题就马上要消除了。
4,内存泄漏是否一定会影响系统性能?
答案是否定的。只要系统资源没有耗尽,多少内存泄漏都不会影响系统的性能。对操作系统本身而言,一些小的性能损失是有的,但是在操作系统稳定运行的范围内。对该进程而言,在没有耗费完资源时,它的性能一定比回收内存的高。
5,内存泄漏减少的是那些系统资源?过程是怎样的?
根本上讲就是:物理内存 + 交换文件,是二者的总大小。这两类资源是所有进程共享的、有限的,用一个少一个。
首先,既然发生了内存泄漏,那么前面一定有分配内存。问题刚刚发生后,这块数据还是在物理内存里的。这就是对物理内存空间的浪费。我们知道,发生了泄漏的内存在进程还活着的时候,是不可能被回收利用的,由于操作系统内存保护的原因,它也不可能被其他进程利用。打狗还得看主人:)
泄漏的内存就暂且留在物理内存中吧。如果这块问题区域所在的页面page内没有其他正常数据的话,就不会再被访问,这个时候,它就要被交换到磁盘上的“交换文件”上来了。于是,对物理内存页面的浪费转变成了对磁盘页面的浪费。当然,如果该页面上还有其他正常数据的话,泄漏的内存还是有可能再通过缺页中断,而被换回物理内存中。
总之,不论是哪种情况,只要发生内存泄漏,物理内存 + 交换文件总的可用资源就会减少。
6,内存泄漏发生的逻辑位置?
进程的逻辑地址空间划分为:代码区,静态区,堆区,栈区。这个逻辑地址空间的管理和组织是由编译器、操作系统、目标机器三者共同完成的。除了堆区,其他三个区里数据对象都是自动管理的,如果这里出现内存泄漏,那么系统就是有严重问题的。对于现在成熟的系统来说,我们可以认为代码区,静态区,栈区,不会发生内存泄漏。
7,Java是否存在内存泄漏问题?
答案是肯定的。即使是具有垃圾回收功能的语言,如Java,不能完全依靠垃圾回收机制。因为回收算法本身的缺陷,在一些对象引用网复杂的情况下,还是可能发生内存泄漏的,在这种场合中需要使用finalize解决问题。