试图了解什么是实际的内存泄漏

时间:2016-08-22 22:47:13

标签: javascript memory-leaks vue.js

我对前端开发很新,目前正在学习Vue.js.当我按照其tutorial时,有一段说:

  

这看起来非常类似于渲染模板,但Vue.js有   在引擎盖下做了很多工作。数据和DOM现在   相关联,现在一切都是被动的。我们怎么知道?打开吧   您的浏览器开发人员控制台和修改exampleData.name 。你应该   请相应地查看上面呈现的示例。

<!-- this is our View -->
<div id="example-1">
  Hello {{ name }}!
</div>
// this is our Model
var exampleData = {
  name: 'Vue.js'
}

// create a Vue instance, or, a "ViewModel"
// which links the View and the Model
var exampleVM = new Vue({
  el: '#example-1',
  data: exampleData
})

在控制台中,我不再修改exampleData.name,而是给exampleData另一个对象exampleData = {}。现在,引用已被修改为指向其他地方,似乎没有引用原始数据(exampleData.name),我想知道这是否是内存泄漏?如果不是,真正的内存泄漏是什么样的情况?

1 个答案:

答案 0 :(得分:0)

JavaScript没有内存泄漏(传统意义上),因为它具有自动垃圾收集功能。 JS解释器为每个对象(包括数字,字符串等)记录引用计数。当引用计数达到0时,将删除该对象(通常使用&#39;标记和扫描&#39;算法)。

因此,在您的示例中,exampleData.name实际上是对某个对象(数字,字符串,JS对象等)的引用,当您输入exampleData.name = {}时,会发生两件事(让&#39;假设exampleData.name最初等于字符串&#34; oldname&#34;):

  1. &#39; {}&#39;创建一个具有单个引用计数的新对象(exampleData.name现在指向它)
  2. 字符串对象&#34; oldname&#34;现在引用计数为0,因为它的唯一引用,exampleData.name,不指向其他内容。现在,下次运行垃圾收集器时,将删除exampleData.name。
  3. 话虽如此,在某些JavaScript场景中,有可能无意中浪费内存(虽然不是传统意义上的内存泄漏),如下面的闭包:

    Public Class Form1
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            If My.Settings.sli Then
                Main.show()
            End If
        End Sub
    
        Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
            If CheckBox1.Checked Then
                My.Settings.sli = 1
            Else
                My.Settings.sli = 0
    
            End If
        End Sub
    
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            My.Settings.user = TextBox3.Text
            My.Settings.pass = TextBox4.Text
            My.Settings.Save()
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            If My.Settings.user = TextBox1.Text And TextBox2.Text = My.Settings.pass Then
                Main.Show()
            Else
                MsgBox("Username Or Password Wrong! Try Again!")
            End If
        End Sub
    End Class
    

    尽管它看起来并不像,但只要浪费了很多,巨型欧宝就会被保留下来。 var存在,因为closureFunc创建的作用域将giantObj的引用计数设置为1。

    至于真实的&#39;内存泄漏,考虑像C ++这样的语言,它没有自动垃圾收集:

    function wastefulFunc(){
        var giantObj = {};
        ///fill giantObj up with thousands of entries
        function closureFunc(){}
        return closureFunc;
    }
    var waste = wastefulFunc();
    

    上面的代码创建了一个指针f,它指向一个显式分配的Foo对象。但是,一旦函数完成,变量f将被销毁,但我们无法引用它指向的内存。由于C ++没有自动垃圾收集,f指向的已分配内存将永远标记为已分配,我们无法释放它,因为我们已经失去了引用它的任何方式!因此,记忆已经泄露了#39;超出我们程序可用的内存池。