显示模块在释放内存时,提示corrupted double-linked
list错误。怀疑是内存泄露,调查了一整天,后来发现某一个通信模块只要不调用其下层的某个API就没有问题。其原因是:该通信模块把对此API的调用写在了回调函数当中。 因为回调函数属于下层模块工作流的一部分,所以要避免在回调函数中直接调用下层的API。 设想一下,上下两层模块运行在不同的线程中,下层提供如下3个接口,FunctionA() 和 NotifyOK(),FunctionB(),其中NotifyOK函数由上层编写、由下层回调。工作流程是:当调用下层的FunctionA之后,要等待下层的回调通知NotifyOK(),之后再调用FunctionB()。而在下层的实现中,当FunctionB被调用时将释放某段内存,这样的话,如果上层在NotifyOK回调函数中调用FunctionB的话,便会产生这样的隐患:假如下层在通过NotifyOK通知上层之后使用了这段内存,便会出现内存泄露(因为其空间已经在NotifyOK回调中被提前释放了)。 安全的做法是:上层在收到NotifyOK之后,不是立即开始进行之后的工作流(调用FuntionB),而是以发消息的方式通知自己进行后续处理。 至于错误发生的时机,是因为释放内存时,堆管理器才会检查标记,发现内存泄露。 另外,还搜索了一下相关资料,了解到一些其它的信息。为了提高运算效率,通常分配的内存空间要大于申请空间(地址对齐)。当发生内存泄露,使用了申请外的空间,但没有超出实际分配空间时,有的早期的堆管理器并不会检查出来(操作系统的内存分配实现算法不相同)。 |
|
来自: waitingnothing > 《Nginx》