由c++之父Bjarne Stroustrup提出,中文翻译为资源获取即初始化。
这种类型的内存管理,对象的内存分配与它的声明周期有关,其核心是把资源和对象的生命周期绑定,对象创建获取资源,对象销毁释放资源。在RAII的指导下,C++把底层的资源管理问题提升到了对象生命周期管理的更高层次。在C++中引入,Ada和Rust也有在用。
自动引用计数。是苹果公司的Objective-C程序的一种自动内存管理机制。
类似于引用计数,但是代替以特定间隔运行,将保留和释放命令插入到代码中,当计数为0时,自动触发, 无需程序暂停。当然ARC依然不能处理循环引用。需要开发者使用某些关键字去处理。
所有权是Rust的突破功能. 它使Rust可以完全内存安全且高效,同时避免垃圾回收。
Rust语言的ownership是rust语言的核心,rust语言之所以被称之为安全的面向系统级别的编程语言 正是由此特性决定的。
rust指南
小结到目前为止,我们简单介绍了内存管理的相关内容,每个语言都有特定的机制,统统不同的算法达到不同的目标,接下里我们来聊聊V8.
V8引擎V8在运行之前将JavaScript编译成了机器代码,而非字节码或是解释执行它,以此提升性能。V8使用C++书写,可以嵌入到任何C++应用程序中。
V8内存结构首先,让我们看下V8引擎内存结构长什么样:
由于js是单线程的,所以node依然会为每个js环境提供单线程环境。如果你在服务端使用,他会为每个服务提供一个进程。在V8程序中,应用程序始终被分配的内存代表。这种内存成为常驻集。如上图所示。
V8中的堆内存这里用来存储对象和动态数据,这是内存中最大的区域,并且是GC工作的地方。不过,并不是所有的堆内存都可以进行GC,只有新生代和老生代被gc管理。堆可以进一步细分为下面这样:
新生代空间:是最新产生的数据存活的地方,这些数据往往都是短暂的。这个空间被一分为二,然后被Scavenger(Minor GC)所管理。稍后会介绍。可以通过V8标志如 --max_semi_space_size 或 --min_semi_space_size 来控制新生代空间大小
老生代空间:是从新生代空间经过至少两轮Minor GC仍然存活下来的数据,该空间被Major GC(Mark-Sweep & Mark-Compact)管理,稍后会介绍。可以通过 --initial_old_space_size 或 --max_old_space_size控制空间大小。
Old pointer space: 存活下来的包含指向其他对象指针的对象
Old data space: 存活下来的只包含数据的对象。
大对象空间: 这是比空间大小还要大的对象,大对象不会被gc处理。
代码空间:这里是JIT所编译的代码。这是除了在大对象空间中分配代码并执行之外的唯一可执行的空间。
map空间:存放 Cell 和 Map,每个区域都是存放相同大小的元素,结构简单。
V8内存管理剖析到目前为止,我们大概了解了内存的各空间组织方式,接下来,让我们看看当程序执行时内存的重要性。
少bb,看代码:
class Employee { constructor(name, salary, sales) { this.name = name; this.salary = salary; this.sales = sales; } } const BONUS_PERCENTAGE = 10; function getBonusPercentage(salary) { const percentage = (salary * BONUS_PERCENTAGE) / 100; return percentage; } function findEmployeeBonus(salary, noOfSales) { const bonusPercentage = getBonusPercentage(salary); const bonus = bonusPercentage * noOfSales; return bonus; } let john = new Employee("John", 5000, 5); john.bonus = findEmployeeBonus(john.salary, john.sales); console.log(john.bonus);点击此处查看代码执行过程中,内存空间的展示
大白话解释一下:
全局向下文像一个快照一样保存在栈上,每一次函数调用也会将一个快照放到栈中,包括函数的局部变量,参数和返回值。
基本类型保存在栈中,对象、复杂类型或者引用类型保存在堆中。
任何函数的调用都会在栈顶被压入。
一旦主进程完成所有任务,堆中的对象便不会被引用而孤立。
随着我们程序的运行,堆中的数据会越来越多,因为无人看管,栈由系统自动管理,所以无需操心。
所以,为了管理堆空间,垃圾回收机制进场了。
我们知道V8如何分配内存空间,接下来让我们看看V8是如何管理堆空间的。
举个简单的例子,V8会释放被孤立的对象,被孤立的对象一般指,不直接或间接被引用的对象,这样就为新对象腾出了空间。
因此,V8垃圾回收机制代表着:回收未使用内存供V8进行复用。
具体的实现如下:
Minor GC (Scavenger)