在C++中,动态内存分配是一把双刃剑,一方面,直接访问内存地址提高了应用程序的性能,与使用内存的灵活性;另一方面,由于程序没有正确地分配与释放造成的例如野指针,重复释放,内存泄漏等问题又严重影响着应用程序的稳定性。
人们尝试着不同的方案去避免这个问题,比较常用的如智能指针,自动垃圾回收等,这些要么影响了应用程序的性能,要么仍然需要依赖于开发者注意一些规则,要么给开发者带来了另外一些很丑陋的用法(实际上笔者很不喜欢智能指针)。因此,优秀的C++内存管理方案需要兼顾性能,易用性,所以到目前为止C++标准都没有给出真正的内存管理方案。
Cocos2d-x的内存管理机制实际上来源于Objective-C,这套机制几乎贯穿Cocos2d-x中所有的动态分配的对象。它使得管理动态分配到堆上的对象更简单,然而它独特的工作机制也使得一些开发者,尤其是不熟悉Objective-C的开发者对其造成一些”误解”。确保完整的理解,以及正确地使用Cocos2d-x的内存管理机制,是使用Cocos2d-x必须具备的基础准备工作。
3.2.1 C++显式堆内存管理
C++使用new关键字在运行时给一个对象动态分配内存,并返回堆上内存的地址供应用程序访问,通过动态分配的内存需要在对象不再被使用时通过delete运算符将其内存归还给内存池。
显式的内存管理在性能上有一定优势,但是极其容易出错,事实上,我们总是不能通过人的思维去保证一个逻辑的正确。不能正确处理堆内存的分配与释放通常会导致以下一些问题:
野指针:指针指向的内存单元已经被释放,但是其他一些指针可能还指向它,这些内存可能已经被重新分配给其他对象,从而导致不可预测的结果。
重复释放:重复释放一个已经被释放的内存单元,或者释放一个野指针(也是重复释放)都会导致C++运行时错误。
内存泄漏:不再被使用的内存单元如果不被释放就会一直占用内存单元,如果这些操作不断重复就会导致内存占用不断增加,在游戏中内存泄漏尤其严重,因为可能每一帧都在创建一个永远不会被回收的游戏对象。
人们尝试着不同的方案去避免这个问题,比较常用的如智能指针,自动垃圾回收等,这些要么影响了应用程序的性能,要么仍然需要依赖于开发者注意一些规则,要么给开发者带来了另外一些很丑陋的用法(实际上笔者很不喜欢智能指针)。因此,优秀的C++内存管理方案需要兼顾性能,易用性,所以到目前为止C++标准都没有给出真正的内存管理方案。
Cocos2d-x的内存管理机制实际上来源于Objective-C,这套机制几乎贯穿Cocos2d-x中所有的动态分配的对象。它使得管理动态分配到堆上的对象更简单,然而它独特的工作机制也使得一些开发者,尤其是不熟悉Objective-C的开发者对其造成一些”误解”。确保完整的理解,以及正确地使用Cocos2d-x的内存管理机制,是使用Cocos2d-x必须具备的基础准备工作。
3.2.1 C++显式堆内存管理
C++使用new关键字在运行时给一个对象动态分配内存,并返回堆上内存的地址供应用程序访问,通过动态分配的内存需要在对象不再被使用时通过delete运算符将其内存归还给内存池。
显式的内存管理在性能上有一定优势,但是极其容易出错,事实上,我们总是不能通过人的思维去保证一个逻辑的正确。不能正确处理堆内存的分配与释放通常会导致以下一些问题:
野指针:指针指向的内存单元已经被释放,但是其他一些指针可能还指向它,这些内存可能已经被重新分配给其他对象,从而导致不可预测的结果。
重复释放:重复释放一个已经被释放的内存单元,或者释放一个野指针(也是重复释放)都会导致C++运行时错误。
内存泄漏:不再被使用的内存单元如果不被释放就会一直占用内存单元,如果这些操作不断重复就会导致内存占用不断增加,在游戏中内存泄漏尤其严重,因为可能每一帧都在创建一个永远不会被回收的游戏对象。