回复: 请教各位大大关于动态内存管理的问题…… 嗯,跟其他人讨论的时候,有的人把ref counted smart pointer当作一种gc;但也有人不认为这是gc,他们认为要采用了内存扫描技术的才能算。
ref counted smart pointer是“类gc”技术里我相对最喜欢的技术了,虽然循环引用问题让人不爽。
关于智能指针的同步问题,我想了一下,可能可以这样做:
首先,每个线程都会有个接收共享对象的接口,在这个接口里,会首先在堆上创建一个智能指针,这个智能指针指向的是传入的共享对象,然后再在桟上建立一个智能指针,它指向的是之前那个堆上的智能指针,当前线程对贡献对象的访问全部通过这个桟上的智能指针(及其副本)完成,而那个堆上的智能指针对象是不会被直接访问的,堆上的智能指针对象的地址也不会被传递给其他线程,如果要把共享对象传递给其他线程,那么就要把堆上的智能指针复制给其他线程。
class SharedObject;//共享对象
typedef SmrtPtr<SharedObject> SharedP;//一级SP
typedef SmrtPtr< SmrtPtr<SharedObject> > SharedPP;//二级SP
SharedObject和SharedP都在堆上建立实例,SharedPP只在桟上建立实例。同一个进程中,对于同一个SharedObject,一个线程里同时最多只有一个SharedP指向它。某个线程里,多个SharedPP指向一个SharedP。当一个线程对SharedObject使用完毕后,它的SharedPP都被销毁,此时线程中的SharedP被销毁。对于一个线程来说,仅仅在接收SharedObject和使用完毕后需要修改SharedObject的refCount,仅需要加锁两次。
这样每个线程仅仅加锁两次,我想大多数应用这也是能够接受的开销。空间上也只是多了一个SharedP。如果把SharedPP做成专门的类,那么使用时也能像普通的SmrtPtr一样方便,并且堆上的那个SharedP可以被完全隐藏起来。
不知道这样能不能达到“或多或少”里的那个“少”的程度。
嗯,每当谈到gc的时候我想到的第一个东西就是java,现在想起来C#里也是有桟的。不过一块内存的直接管理者只能是这两者之一,所以还是有个选择问题的。
在大多数情况下,gc会降低我对我的代码的理解程度。如果说没有gc时理解各种各样的存储管理会很费力,那么有了gc后,很多存储管理我是想看都看不到了。所以如果使用gc的话,付出的代价就是对程序掌控的减弱,当然其中还有gc与RAII难溶这一因素。
所以虽然以后C++会加入gc,但是我仍然把gc当作最后的选项。
^_^! |