垃圾回收机制和内存管理_内存管理和垃圾回收

垃圾回收机制和内存管理

In programming languages like C and C++, there are two types of memory allocation: static and dynamic. Static memory allocation is what happens when we create a global or local variable with a single fixed size. The program allocates once when the program is started and never frees it until the application ends execution. Examples in C and C++ include typed variables and arrays. The other type is dynamic memory allocation. We can create these ‘objects’ with any size using malloc(), and the number of bytes they contain can be altered during runtime using realloc(). We can free the memory things allocated this way manually using free().

在诸如C和C ++的编程语言中,有两种类型的内存分配:静态和动态。 当我们创建一个具有单个固定大小的全局或局部变量时,就会发生静态内存分配。 程序在启动时分配一次,并且在应用程序结束执行之前永远不会释放它。 C和C ++中的示例包括类型化变量和数组。 另一种类型是动态内存分配。 我们可以使用malloc()创建任何大小的“对象”,并且可以在运行时使用realloc()更改它们包含的字节数。 我们可以使用free()手动释放以这种方式分配的内存。

Image for post
an example of what dynamic memory allocation looks like in C
C语言中动态内存分配的示例

These things can create unforeseen memory leaks as well as complications, like the need to know the difference between a variable(static) and a pointer (dynamic) or between an array (fixed length) and a linked list (with a size that can change dynamically). People have been using C and C++ both for a very long time, and these languages are probably not going away any time soon, but fortunately, many languages today abstract these concepts away from the programmer.

这些事情会造成无法预料的内存泄漏以及复杂性,例如需要知道变量(静态)与指针(动态)或数组(固定长度)与链表(大小可以改变)之间的差异。动态地)。 人们使用C和C ++已有很长时间了,这些语言可能不会很快消失,但是幸运的是,当今许多语言都从程序员那里抽象了这些概念。

Languages like Java, C#, JavaScript, and Ruby abstract away all of these things away from the programmer using a system known as Garbage Collection. There are a few approaches that the collector like the one in JS uses. Still, the basic idea is something called the Memory Cycle: we allocate the memory, the program uses that memory, and then when the memory is not needed anymore, the garbage collector frees that memory.

大号 anguages像Java,C#,JavaScript和Ruby的抽象掉的这些东西远离使用被称为垃圾收集系统程序员。 像JS中的收集器那样,收集器使用了几种方法。 仍然,基本思想是所谓的“内存循环”:我们分配内存,程序使用该内存,然后当不再需要该内存时,垃圾收集器将释放该内存。

Image for post
Memory Life Cycle
记忆生命周期

JavaScript allocates memory automatically when a variable, object, or function gets created. The garbage collector looks for a good reason to free this memory during runtime, and there are a couple of algorithms that can help to achieve this goal.

创建变量,对象或函数时,JavaScript自动分配内存。 垃圾收集器寻找在运行时释放此内存的充分理由,并且有两种算法可以帮助实现此目标。

参考计数垃圾收集 (Reference Counting Garbage Collection)

Reference-counting garbage collection is the most naive approach to garbage collection. It checks not so much whether an object is still needed, but whether or not any other variables or objects contain a reference to it. An item is determined to be ‘garbage’ and collected if the number of references to that object is zero.

引用计数垃圾收集是最幼稚的垃圾收集方法。 它检查的不是是否仍然需要对象,而是检查是否有其他变量或对象包含对该对象的引用。 如果对该对象的引用数为零,则将其确定为“垃圾”并收集。

Image for post
example 1
例子1

There are limitations to this method, however. If we create two variables in a function’s scope and set one of their properties equal to the other object. When we call the function, the program allocates memory for both objects. Still, since they are circularly referenced, i.e., they reference each other, a garbage collector working with a reference counting algorithm will not mark these objects as garbage because they still have references, even though the program leaves the scope of the function! We have a problem now if we call a function like this many many times, this is a massive memory leak!

但是,此方法有局限性。 如果我们在函数的范围内创建两个变量,并将它们的一个属性设置为与另一个对象相等。 当我们调用函数时,程序将为两个对象分配内存。 尽管如此,由于它们是循环引用的,即它们彼此引用,所以使用引用计数算法的垃圾收集器不会将这些对象标记为垃圾,因为即使程序离开了函数的范围,它们仍然具有引用! 现在,如果我们多次调用这样的函数,就会遇到问题,这是一个巨大的内存泄漏!

Image for post
example 2 — circular reference
示例2 —循环引用

标记扫描算法 (Mark-and-Sweep Algorithm)

The second, smarter algorithm, is known as Mark-and-Sweep. Instead of naively counting simple references to an object or variable, mark and sweep will instead free memory once the variable is unreachable, like in the case of our second circularly referenced variables. As the name suggests, this is a two-pass algorithm that first marks objects for deletion and then ‘sweeps away’ the memory in the second pass.

第二种更智能的算法称为标记扫描。 一旦变量不可访问,就像我们第二个循环引用的变量一样,标记和清除操作不会天真地计算对对象或变量的简单引用,而是释放内存。 顾名思义,这是一种两次通过算法,该算法首先将对象标记为删除,然后在第二次通过中“清除”内存。

The central concept here is reachability. There are a set of variables that are reachable by definition and which garbage collection will not delete: root variables. These include variables/parameters local to the current function, variables/parameters for other functions in the existing chain of function calls, and global variables. A non-root variable is reachable if there is a reference to it by any of the root variables. This way, once a variable falls out of scope, it is no longer a root variable and is marked for garbage collection.

这里的中心概念是可达性。 有一组变量是可以定义的,并且垃圾回收不会删除:根变量。 这些包括当前函数局部的变量/参数,现有函数调用链中其他函数的变量/参数以及全局变量。 如果任何根变量都引用了非根变量,则该非根变量是可访问的。 这样,一旦变量超出范围,它就不再是根变量,并被标记为垃圾回收。

In conclusion, even though we have no control over how and when memory gets allocated/freed in higher-level languages, the magic of garbage collection gives programmers one less thing to worry about, even if it is just in a minor way.

总之 ,尽管我们有过如何以及何时内存被分配/释放在高级语言无法控制,垃圾收集的魔法使程序员操心少了一个东西,即使它只是在一个小的方式。

资料来源: (Sources:)

翻译自: https://medium.com/dev-genius/memory-management-and-garbage-collection-3b9660ccf7ba

垃圾回收机制和内存管理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值