大一学了C++,上学期又上过Java课,二者有相当多的相似之处,但内存管理机制却有着很大的区别。在C++中,程序员需要自己管理内存,而Java中则完全依靠JVM提供垃圾回收机制。C++人工管理内存程序效率高,但需时时小心;Java则恰恰相反,JVM负责内存的管理,安全性、健壮性可以得到保证,但需要有时时扫描监听实例对象导致效率较低。关于这点,我平时编程中是深有体会的。之前做ACM,用Java解题的限时比C++宽松很多,我想有些原因就在这吧。
Java中的垃圾回收机制
先谈谈Java中的垃圾回收机制。Java中的垃圾回收机制的目的在于回收释放不再被引用的实例对象占用的内存空间。垃圾回收通过确定内存单元是否还被对象引用来确定是否收集该内存区。垃圾回收首先要判断该对象是否是时候可以收集。两种常用的方法有2种,分别是引用计数器和对象引用遍历。
引用计数器的原理是设置一整形变量来记录当前对象是否被引用以及引用的次数。当一个对象被创建时,将该对象对应计数器设置初值为1。当有新引用指向对象时,计数器+1;当其中某些引用超过生命期时,计数器-1.当计数器变为0时就可以当做垃圾收集了。这种方法实现简单,效率相对较高;但出现交叉引用时难以处理。下面是原文举例说明“父对象有一个对子对象的引用,子对象反过来引用父对象。这样,他们的引用计数永远不可能为0”。
较早版本的JVM使用引用计数器,现在大多数JVM采用对象引用遍历。对象引用遍历从一组对象出发,沿着整个对象关系图上的每条链接线,递归确定当前可达的对象。如果某对象不能从这些根对象中的任何一个到达,则将它作为垃圾收集。等待它的就是删除,释放存储空间了。
我所查阅的资料就是上面两种典型的,可能大家还有其他见解。
C++中智能指针
C++中提到的开发人员自己管理内存主要体现在动态申请内存空间及其释放过程。在编程时,我们经常需要动态申请存储单元,这样可以回避静态开辟的诸多弊端,如new,malloc等,还要记得在不在使用时释放delete,free等。当然很多情况下,这等操作是简单且不会出错的。但是,要保证程序的健壮性,必须时时注意是否有如内存泄露、悬垂指针等问题。处理这个问题也有比较多的想法,如设置计数器、直接进行值操作(这里指传说中的深拷贝)等,但C++不同于其他语言,C++有指针这一特色。指针可以类比其他语言的引用,但实现原理、运用方法还是有些区别的,鉴于水平有限不可能说的很通透在此就不多说了。C++解决该类问题有一个有效的特色方法-智能指针。智能指针的出现是为了解决某个对象存储单元释放可能带来的潜在风险。含有指针成员的类需要特别注意复制和赋值操作,原因是复制指针时只复制指针中的地址,而不会复制指针指向的对象(这就是传说中的浅拷贝吧),最终都指向同一内存单元。当某个对象在析构的时候,可能释放了改存储单元,但仍然有指针指向该段内存区,可能会导致垂悬指针问题。指向相同内存单元的智能指针指向相同的辅助指针类,该类包含计数器以及具体存储单元指针。截张不是很有联系的图表示对应关系:
转自http://blog.csdn.net/hustyangju/article/details/23827195,在此表示感谢!
#include<iostream> #include<string> using namespace std; /************************************************** *具体类 ***************************************************/ class Car { private: string number; public: Car(string tempNumber):number(tempNumber) { } Car():number("null") { } string GetCarNumber() { return this->number; } void SetCarNumber(string tempNumber) { this->number=tempNumber; } }; /************************************************** *辅助指针类,包含计数器以及有意义的指针, ***************************************************/ class AssistPtrCar { private://全部成员为私有控制外部访问 friend class SmartPtrCar;//定义友元类 int countCar; Car *ptrCar; AssistPtrCar(Car* tempPtrCar):ptrCar(tempPtrCar),countCar(1) { } ~AssistPtrCar() { delete ptrCar; } }; /************************************************** *智能指针类 ***************************************************/ class SmartPtrCar { private: AssistPtrCar *ptrAssistCar; public: SmartPtrCar(Car *tempPtrCar) { this->ptrAssistCar=new AssistPtrCar(tempPtrCar); } SmartPtrCar(const SmartPtrCar &tempPtrSmartPtrCar) { this->ptrAssistCar=tempPtrSmartPtrCar.ptrAssistCar; ++(this->ptrAssistCar->countCar); } SmartPtrCar &operator=(const SmartPtrCar &tempPtrSmartPtrCar) { if(this==&tempPtrSmartPtrCar||this->ptrAssistCar==tempPtrSmartPtrCar.ptrAssistCar) //防止智能指针自赋值,同时防止辅助指针自赋值,可以不要,后面语句也能完成相似功能 return *this; ++(tempPtrSmartPtrCar.ptrAssistCar->countCar); if(0==--this->ptrAssistCar->countCar) /*释放原来所指的对象,此处配合 *++(tempPtrSmartPtrCar.ptrAssistCar->countCar); *可以完成自赋值 */ delete this->ptrAssistCar; this->ptrAssistCar=tempPtrSmartPtrCar.ptrAssistCar; return *this; } ~SmartPtrCar() { if(0==--this->ptrAssistCar->countCar) delete this->ptrAssistCar; } }; int main() { Car *ptrCar1=new Car("A1000"); Car *ptrCar2=new Car("A1000"); SmartPtrCar mySmartPtrCar1(ptrCar1); SmartPtrCar mySmartPtrCar2(ptrCar2); SmartPtrCar mySmartPtrCar3(mySmartPtrCar1); mySmartPtrCar2=mySmartPtrCar1; return 0; }
时间有限,缺乏测试,如有不足,欢迎斧正!
[codility]MaxCounters,布布扣,bubuko.com
原文:http://blog.csdn.net/sunbaigui/article/details/24201921