内存泄漏专题

Li Guangqiao - 13/05/2023

Memory leak

内存泄漏

什么是内存泄漏?

内存泄漏指的是在计算机程序中动态分配的内存空间在不再被使用时没有被正确释放或回收的情况。当发生内存泄漏时,程序持续占用着一部分内存,而这些内存无法被其他部分或其他程序使用,从而导致系统的可用内存逐渐减少。

内存泄漏可能由以下情况引起:

  1. 动态内存分配未释放:在程序中使用诸如malloc、new等函数或操作符分配内存空间时,如果没有及时调用对应的释放函数或操作符,就会导致内存泄漏。例如,在C++中使用new操作符分配对象的内存,如果没有使用delete操作符释放内存,就会发生内存泄漏。
  2. 数据结构中的循环引用:在某些情况下,数据结构中的对象之间可能存在循环引用关系,即对象A引用对象B,对象B又引用对象A,而且这些对象都不再被程序使用。这种情况下,即使这些对象不再需要,由于彼此之间存在引用关系,它们无法被垃圾回收器正确回收,从而导致内存泄漏。
  3. 文件或资源未关闭:在使用文件、网络连接、数据库连接等外部资源时,如果没有正确关闭或释放这些资源,就会导致内存泄漏。即使程序不再使用这些资源,但操作系统或底层库可能仍然保持着相关的内存空间。

内存泄漏会导致程序运行时占用的内存不断增加,最终可能导致系统的内存耗尽或程序性能下降。为了避免内存泄漏,开发者应当注意及时释放动态分配的内存,处理对象之间的引用关系,以及正确关闭文件和其他资源。使用合适的内存管理技术和工具,例如自动垃圾回收(Garbage Collection)或智能指针,也可以帮助减少内存泄漏的风险。

js中的内存泄漏

在JavaScript中,内存泄漏是指无用的对象仍然被占用内存,而无法被垃圾回收器释放的情况。JavaScript中的内存泄漏通常是由以下情况引起的:

  1. 未及时清理定时器和事件监听器:在JavaScript中使用定时器(setTimeout或setInterval)或事件监听器(addEventListener)时,如果没有及时清理它们,即使它们不再需要,它们仍然保留对回调函数的引用,导致相关对象无法被垃圾回收。
  2. 循环引用:如果存在对象之间的循环引用,即对象A引用了对象B,而对象B又引用了对象A,并且没有其他部分引用这些对象,就会发生内存泄漏。即使这些对象已经不再被程序使用,但由于它们之间的引用关系,垃圾回收器无法正确回收它们所占用的内存。
  3. 未释放的DOM元素引用:在JavaScript中,如果在页面中创建了DOM元素的引用,但在后续不再需要时未及时释放,就会发生内存泄漏。即使从页面中删除了这些元素,它们仍然被引用,无法被垃圾回收器回收。
  4. 闭包引用:JavaScript中的闭包函数可以访问其外部作用域的变量,如果在闭包函数中引用了外部作用域的变量,而闭包函数本身又没有被及时释放,就会导致引用的变量无法被垃圾回收。
  5. 未释放的资源:在JavaScript中涉及到外部资源的操作,如网络请求、数据库连接等,如果没有正确释放这些资源,就会导致内存泄漏。这些资源可能占用系统内存或浏览器资源,而没有被及时释放。

为了避免JavaScript中的内存泄漏问题,开发者可以采取以下措施:

Li Guangqiao
Li Guangqiao

一个正在转rust的ExtJs前端工程师。迷信rust的整体发展,十分相信rust在各个领域都能发光发热,至少目前rust在很多领域上验证了其安全性、易维护性。但说实话对于我这种菜鸡也是真的难上手哈哈哈~~。 思路总结:

  • 万物诞生都会有一个需求来源,每一个改变都是为了解决某个问题,最后应该考虑如何去做
  • 学会掌握一些宏观的知识和理论:系统论、还原论
  • 工程化思想,如何描述整体,从整体架构到模块关联等 故学习东西应该像看地图一样,先看整体了解整体的结构,然后再聚焦每一个模块,对于模块的学习,思考三个问题,“是什么?”、“为什么?”、“怎么做?”;那么设计一个东西时也应该去考虑整体性和关联性。

有关于未来的发展,以下是鄙人的粗浅的观点:

  • 编程语言未来应该是每个人必备的工具
  • 未来的交互方式应该会以语言交互为主流
  • 下一个去中心化的技术方案出来之前,区块链依然是web3建立价值体系的基础技术方案,如何将现实价值和虚拟价值联通是进入数字世界的一个大难题。
  • 未来注定是AI的世界。AI的进化会伴随绝大部分人的退化,届时除了尖端人才,人们学习的重心会放在何处?