程序语言中内存管理-DO NOT STOP THE WORLD
类似枪械有手动步枪-M1903春田,半自动步枪-M1,自动步枪-M16之分,程序语言的内存管理也有手动、半自动和全自动三种方式。手动内存管理的代表语言:C、C++,半自动内存管理的代码语言:Modern C++,Swift,Rust,全自动的代表语言:Java,C#,Go,Python。本文通过不同程序语言来描述三种内存管理方式,以及如何应对循环引用的典型场景。 手动内存管理: 为了实现代码的极致效率以及灵活性C和C++语言采用了手动内存管理方式,通过自己编写代码实现堆上的内存分配与回收。 //C++代码示例 export class Manual { public: Manual(int s) :elem{ new double[s] }, sz{ s } {} ~Manual() { delete[] elem; } private: double* elem; int sz; }; 半自动内存管理: 内存泄漏是手动内存管理遇到最大的挑战,在复杂的场景下可能出现分配的内存没有释放,导致程序在特殊的情况下内存耗尽停止工作。为了保证内存安全,新一代语言为了不牺牲效率采用编译时期来分析内存的分配与释放,典型的方式是自动引用计数(Automatic Reference Counting ) //swift代码示例 class ARC { } func usingARC() { var ref1: ARC? = ARC() var ref2: ARC? = ref1 ref1 = nil ref2 = nil //ref1、ref2 已释放 } //Modern C++ export class SmartPointers { public: //represents unique ownership (its destructor destroys its object) void uniquePtr() { std::unique_ptr<X> sp{ new X }; std::unique_ptr<X> sp3 = std::make_unique<X>(); std::unique_ptr<X> sp2 = std::move(sp); } //represents shared ownership (the last shared pointer¡¯s destructor destroys the object) void sharedPtr() { std::shared_ptr<X> sp = std::make_shared<X>(); std::shared_ptr<X> sp2 = sp; sp.reset(); sp2.reset(); } //A pointer to an object owned by a shared_ptr void weakPtr() { std::shared_ptr<X> sharedPtr = std::make_shared<X>(); // Creating a weak pointer from the shared pointer std::weak_ptr<X> weakPtr = sharedPtr; // Using the weak pointer to access the object if (auto ptr = weakPtr.lock()) { } else { std::cout << "Weak pointer is expired." << std::endl; } // Resetting the shared pointer sharedPtr.reset(); // Using the weak pointer again after resetting the shared pointer if (auto ptr = weakPtr.lock()) { } else { std::cout << "Weak pointer is expired." << std::endl; } } }; 全自动内存管理: 同样保证内存安全,同时减少内存管理心智负担,还有一种全自动内存管理-垃圾回收机制(GC)。但这种方式引入了臭名昭著的STOP THE WORLD。 ...