垃圾回收

JVM-垃圾回收 垃圾回收及其算法 阅读详情
1、小整数对象池

​ 在程序中整数的使用非常的广泛,Python为了优化速度,使用了小整数对象池,避免为 整数频繁申请和销毁内存的空间。

​ Python中对象小整数的定义时[-5,256],这些整数的对象时提前建立好的,不会被垃圾回收。在一个Python的程序中,所有位于这个范围内的整数使用的都是同一个对象。

In [1]: a = -5

In [2]: id(a)
Out[2]: 10911520

In [3]: b = -5

In [4]: id(b)
Out[4]: 10911520

In [5]: c = 256

In [6]: id(c)
Out[6]: 10919872

In [7]: d = 256

In [8]: id(d)
Out[8]: 10919872

In [9]: e = 257

In [10]: id(e)
Out[10]: 139826489334128

In [11]: f = -6

In [12]: id(f)
Out[12]: 139826489334064

​ 上面中,我们可以看到范围在[-5,256]之间的整数,包含-5和256,对象在内存中的地址是相同的,同理,单个字母也是这样。

​ 但是当定义两个相同的字符串时,引用计数为0,那么就会触发垃圾回收。

2、大整数对象池

​ 每一个大整数,均创建一个新的对象。

In [14]: a = 1234

In [15]: id(a)
Out[15]: 139826489334576

In [16]: b = 1234

In [17]: id(b)
Out[17]: 139826489334640

3、intern机制

​ 假如有好多个对象:

a1 = "HelloWorld"
a2 = "HelloWorld"
a3 = "HelloWorld"
a4 = "HelloWorld"
a5 = "HelloWorld"
a6 = "HelloWorld"
a7 = "HelloWorld"
a8 = "HelloWorld"

​ python会不会创建8个对象呢?会不会在内存中开辟8个内存 空间?

​ 答案是不会的,想一下,如果我们写10000个对象,像上面那样,那岂不是会在内存中开辟10000个空间,那得占用多少的内存。所以在Python中有这样的一个机制—->intern机制,

让他只占用一个“HelloWorld”所占的空间,靠引用计数去维护何时释放。

In [19]: a = 'abcd'

In [20]: id(a)
Out[20]: 139826471344368

In [21]: b = 'abcd'

In [22]: id(b)
Out[22]: 139826471344368

In [23]: c = b

In [24]: id(c)
Out[24]: 139826471344368

In [25]: del a

In [26]: del b

In [27]: id(c)
Out[27]: 139826471344368
总结
  • 小整数[-5,256]共用内存,常驻内存。

  • 单个字符公用内存,常驻内存

  • 单个单词,不可修改,默认开启intern机制,公用内存,引用计数为0,则销毁

  • 字符串(含有空格),不可修改,没开启intern机制,不共用对象,引用计数为0,销毁

    In [30]: a = 'hello world'
    
    In [31]: b = 'hello world'
    
    In [32]: id(a)
    Out[32]: 139826489193264
    
    In [33]: id(b)
    Out[33]: 139826489192816
    
    In [34]: c = 'helloworld'
    
    In [35]: d = 'helloworld'
    
    In [36]: id(c)
    Out[36]: 139826486896048
    
    In [37]: id(d)
    Out[37]: 139826486896048
    
  • 大整数不共用内存,引用计数为0,销毁

  • 数值类型和字符串类型在Python中都是不可变的数据类型,这意味着你无法修改这个对象的值,每次对变量的修改,实际上是创建了一个新的对象。

    In [39]: a = 110
    
    In [40]: id(a)
    Out[40]: 10915200
    
    In [41]: a += 1
    
    In [42]: id(a)
    Out[42]: 10915232
    
    In [43]: b = 'hello'
    
    In [44]: id(b)
    Out[44]: 139826471345768
    
    In [45]: b = 'world'
    
    In [46]: id(b)
    Out[46]: 139826471344368
    
    
**4、**Garbage collection(GC垃圾回收)

​ python采用的是引用计数机制为主,分代收集机制为辅的策略

​ 当引用计数为0时,该对象的生命就结束了

​ 引用计数机制的优点:

  • 简单

  • 实时性:一旦没有引用,即引用计数为0,内存就直接释放了。不用像其他机制等到特定的时机,实时性还带来一个好处:处理回收内存的时间分摊到了平时

    引用计数机制的缺点:

  • 维护引用计数消耗资源

  • 循环引用

    list1 = []
    list2 = []
    list1.append(list2)
    list2.append(list1)

    list1与list2相互引用,如果不存在其他对象对它们的引用,list1与list2的引用计数也仍然为1,所占用的内存永远无法被回收,这将是致命的。对于如今的强大硬件,缺点1尚可接受,但是循环引用导致内存泄露,注定python还将引入新的回收机制。(分代收集)

    GC系统所承担的工作远比”垃圾回收”多得多。实际上,它们负责三个重要任务:

    • 为新生成的对象分配内存
    • 识别哪些垃圾对象
    • 从垃圾对象那回收内存
5、垃圾回收机制
  • 1、导致引用计数+1的情况

    • 对象被创建,如:a = 10
    • 对象被引用,如:b = a
    • 对象被作为参数,传递到一个函数中,如:func(a)
    • 对象作为一个元素,存储在容器中,如:list = [a, a]
  • 2、导致引用计数-1的情况:

    • 对象的别名被显示销毁,如:del a
    • 对象的别名被赋予新的对象,如:a = 20
    • 一个对象离开他的作用域, 如函数f执行完毕时,func函数中的局部变量(全局变量不会)
    • 对象所在的容器被销毁,或从容器中删除对象
  • 3、查看一个对象的引用计数

    import sys
    a = "hello world"
    sys.getrefcount(a)

    可以查看a对象的应用计数,但是比正常计数大1,因为在调用函数的时候传入a,这会让a的引用计数+1

6、循环引用导致内存泄露

​ 内存泄露:

​ 申请了某些内存,但是忘记了释放,那么这就造成了内存的浪费,久而久之内存就不够用了.

import gc

class ClassA():
    def __init__(self):
        print('object born,id:%s'%str(id(self)))

def f2():
    while True:
        c1 = ClassA()
        c2 = ClassA()
        c1.t = c2
        c2.t = c1
        del c1
        del c2

#python默认是开启垃圾回收的,可以通过下面代码来将其关闭
gc.disable()

f2()

​ 执行f2(),进程占用的内存会不断增大。

  • 创建了c1,c2后这两块内存的引用计数都是1,执行c1.t=c2和c2.t=c1后,这两块内存的引用计数变成2.
  • 在del c1后,引用计数变为1,由于不是为0,所以c1对象不会被销毁;同理,c2对象的引用数也是1。
  • python默认是开启垃圾回收功能的,但是由于以上程序已经将其关闭,因此导致垃圾回收器都不会回收它们,所以就会导致内存泄露。
7、垃圾回收
class ClassA():
    def __init__(self):
        print('object born,id:%s'%str(id(self)))

def f2():
    while True:
        c1 = ClassA()
        c2 = ClassA()
        c1.t = c2
        c2.t = c1
        del c1
        del c2
        gc.collect()#手动调用垃圾回收功能,这样在自动垃圾回收被关闭的情况下,也会进行回收

#python默认是开启垃圾回收的,可以通过下面代码来将其关闭
gc.disable()

f2()

​ 有三种情况会触发垃圾回收

  • 当gc模块的计数器达到阀值的时候,自动回收垃圾
  • 调用gc.collect(),手动回收垃圾
  • 程序退出的时候,python解释器来回收垃圾
**8、**gc模块的自动垃圾回收触发机制

在Python中,采用分代收集的方法。把对象分为三代,一开始,对象在创建的时候,放在一代中,如果在一次一代的垃圾检查中,改对象存活下来,就会被放到二代中,同理在一次二代的垃圾检查中,该对象存活下来,就会被放到三代中。

gc模块里面会有一个长度为3的列表的计数器,可以通过gc.get_count()获取。

例如(488,3,0),其中488是指距离上一次一代垃圾检查,Python分配内存的数目减去释放内存的数目,注意是内存分配,而不是引用计数的增加。例如:

print gc.get_count() # (590, 8, 0)
a = ClassA()
print gc.get_count() # (591, 8, 0)
del a
print gc.get_count() # (590, 8, 0)

3是指距离上一次二代垃圾检查,一代垃圾检查的次数,同理,0是指距离上一次三代垃圾检查,二代垃圾检查的次数。

gc模快有一个自动垃圾回收的阀值,即通过gc.get_threshold函数获取到的长度为3的元组,例如(700,10,10),每一次计数器的增加,gc模块就会检查增加后的计数是否达到阀值的数目,如果是,就会执行对应的代数的垃圾检查,然后重置计数器。

例如,假设阀值是(700,10,10):

当计数器从(699,3,0)增加到(700,3,0),gc模块就会执行gc.collect(0),即检查一代对象的垃圾,并重置计数器为(0,4,0)
当计数器从(699,9,0)增加到(700,9,0),gc模块就会执行gc.collect(1),即检查一、二代对象的垃圾,并重置计数器为(0,0,1)
当计数器从(699,9,9)增加到(700,9,9),gc模块就会执行gc.collect(2),即检查一、二、三代对象的垃圾,并重置计数器为(0,0,0)
人形机器人触觉革命:压电式电子皮肤的多模态感知与自修复技术突破 本文深入探讨了压电式电子皮肤如何推动人形机器人的触觉革命。文章分析了其基于压电效应的多模态感知原理,能够灵敏检测压力、振动与温度,并重点介绍了赋予电子皮肤自修复能力的动态共价网络等前沿材料技术,从而极大提升了机器人与物理世界进行精细、安全交互的可靠性与智能化水平。 阅读详情

相关推荐

3GPP协议解读_NTN系列(一)_38.811_非地面网络(NTN)的背景、应用场景和信道建模

非地面网络覆盖广,对物理攻击和自然灾害有一定的抵抗性。本文根据3GPP协议对NTN网络的背景、应用场景和信道模型进行了整理。

JCMLSY的博客 4932

Python垃圾回收机制详解

我们从三个方面来了解一下Python的垃圾回收机制。一、引用计数   Python垃圾回收主要以引用计数为主,分代回收为辅。引用计数法的原理是每个对象维护一个ob_ref,用来记录当前对象被引用的次数,也就是来追踪到底有多少引用指向了这个对象,当发生以下四种情况的时候,该对象的引用计数器+1  与上述情况相对应,当发生以下四种情况时,该对象的引用计数器-1下面来补充一下它的源码分析: Python里面每一个东西都是对象,他们的核心是一个结构体Py_Object,所有Python对象的头部包含了这样一个结构P

2301_76965813的博客 4791

PaddleOCR转ONNX模型实战:5分钟搞定中文OCR推理部署(附完整代码)

本文详细介绍了将PaddleOCR模型转换为ONNX格式并进行高效推理部署的完整实战方案。通过Paddle2ONNX工具实现模型转换,利用ONNX Runtime构建跨平台推理引擎,涵盖环境配置、模型优化、批量处理及多平台部署等关键步骤,显著提升中文OCR在边缘设备上的推理性能。

weixin_29051811的博客 617

python垃圾回收机制详解

Python 是一门解释性编程语言,它的内存管理不像 C 和 C++ 一样有显式的内存分配和释放动作。Python 的内存分配和释放都是自动完成的,这往往会带来一些内存管理上的问题,如内存泄漏等。Python 的垃圾回收机制是解决这类问题的重要手段之一。Python 的垃圾回收机制是自动的,而非强制的,Python 在解释程序执行时,使用了类似于引用计数的技术来实现垃圾回收。

naer_chongya的博客 2372

什么是论文的创新点?公式化描述算是创新点吗?

写科研论文时,挑战之一就是如何让你的工作“脱颖而出”,也就是要有创新性。不管实验多么精确、推导多么复杂,若没有真正的创新,论文很可能会被拒。关于如何创新问题上,我最近在看刘雪峰老师的《科技论文写作指南》,看到了很多关于写作的新论述,在这里和大家进行分享。

加百力 的技术博客 1928

MySQL等保三级合规实践:如何安全配置root账户的本地与受信主机登录策略

本文详细介绍了MySQL在等保三级合规框架下如何安全配置root账户的本地与受信主机登录策略。通过分析root账户的特殊保护需求,提供三种安全加固方案,包括限制访问范围、限定登录IP和完全禁止远程登录,并指导创建安全的远程管理账户。文章还涵盖了密码策略强化、日志审计配置和网络层防护等关键合规要求,帮助用户实现MySQL的等保三级全面合规。

weixin_42522964的博客 260

【python】python的垃圾回收机制(详细讲解)

在大多数情况下,不需要关心Python的垃圾收集机制,因为它会自动地在后台工作。但如果你在编写大型的或内存密集的程序,理解垃圾收集机制有助于更好地管理内存。这个周期性垃圾收集器是在引用计数的基础上运行的,并且它只处理可能引起循环引用的对象。这种处理机制更加复杂,需要花费更多的计算资源,因此Python不会频繁地运行它,而是在一定的时间间隔后运行。

测试开发自动化 2374

ZYNQ实战:PS端驱动DMA实现高效数据流转与验证

本文详细介绍了在ZYNQ平台上通过PS端驱动DMA实现高效数据流转的实战方法。从ZYNQ的PS与PL数据交互基础出发,深入解析DMA核心价值,包括硬件平台搭建、Vivado配置、PS端软件架构设计及性能优化技巧,帮助开发者提升数据传输效率与系统性能。

weixin_29192141的博客 439

Python 的垃圾回收机制(GC-GarbageCollection)

总体来说,在Python中,主要通过引用计数进行垃圾回收;通过 “标记-清除” 解决容器对象可能产生的循环引用问题;通过 “分代回收” 以空间换时间的方法提高垃圾回收效率。

TFATS的博客 2809

Rockchip RK3568实战:手把手教你调试I2S音频驱动(附ALSA设备树配置详解)

本文提供Rockchip RK3568平台I2S音频驱动的实战调试指南。详细解析了从硬件连接到软件配置的全过程,重点涵盖ALSA驱动框架下的设备树配置、时钟计算、DMA参数设置以及常见问题(如无声、爆音)的排查与解决方法,帮助开发者快速定位并解决音频驱动难题。

weixin_28358083的博客 500

保姆级教程:在NXPS32144环境下安装EB TRESOS 29.0.0并配置MCAL开发环境

本文提供了一份详细的保姆级教程,指导如何在NXP S32K144环境下安装EB TRESOS 29.0.0并配置MCAL开发环境。内容涵盖从前期资源准备、软件安装步骤、核心的MCAL关联配置,到首次创建AUTOSAR工程并进行模块配置的全流程,旨在帮助汽车电子开发者搭建稳定、可用的底层软件开发地基。

wind6的博客 961

一文读懂Python垃圾回收机制【收藏版】

得益于的自动垃圾回收机制,在中创建对象时无须手动释放。这对开发者非常友好,让开发者无须关注低层内存管理。但如果对其垃圾回收机制不了解,很多时候写出的代码会非常低效。垃圾回收算法有很多,主要有:、、等。引用计数原理比较简单:在中,可以通过模块的函数获取指定对象的引用计数器的值,我们以实际例子来看。 运行上面代码,可以得到输出结果为。上面我们看到,创建一个对象,并将对象赋值给变量后,对象的引用计数器值为。那么什么时候计数器会,什么时候计数器会呢?为了更好的理解计数器的增减,我们运行实际代码,一目了然。 输出结果

huachao1001的专栏 5182

DDS信号发生器设计避坑指南:从AD9834配置到巴特沃斯滤波实战

本文详细解析了基于AD9834芯片的DDS信号发生器设计中的关键技术要点与常见陷阱,涵盖时钟源选择、寄存器配置时序、巴特沃斯滤波器设计等核心内容。针对中高频段信号质量优化,提供了实用的解决方案和代码示例,帮助工程师规避设计误区,提升信号发生器的性能和稳定性。

2y3u4i5o6p的博客 785

JVM中垃圾回收

JVM中的垃圾回收是通过对堆内存进行管理、清理无用对象,从而确保应用的高效运行。整个垃圾回收过程包括对象的分代存储、不同的垃圾回收算法(标记-清除、复制、标记-整理等),以及多种垃圾回收器(Serial GC、Parallel GC、CMS GC、G1 GC等)来适应不同的应用场景。优化垃圾回收是一个综合的过程,需要根据应用的特性选择合适的垃圾回收器,并通过合理的内存分配、减少对象创建与销毁、调优对象晋升策略等方法减少GC对应用性能的影响。

yymagicer的博客 2261

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

java八股-垃圾回收机制-垃圾回收算法,分代回收,垃圾回收器

深入的图文并茂讲解垃圾回收器,垃圾回收算法,分代回收

weixin_46028606的博客 2772

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

一文整明白js中垃圾回收,垃圾回收的机制,为什么有垃圾回收

讲述了js中为什么有垃圾回收,垃圾回收的机制

weixin_64104823的博客 1803

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

一文看懂:JVM垃圾回收算法、CMS垃圾回收器、G1垃圾回收器

Hello,大家好,我是此林。今天我们来聊一聊 JVM 垃圾回收机制。在C/C++这类没有自动垃圾回收机制的语言中,一个对象如果不再使用,需要手动释放,否则就会出现内存泄漏。内存泄漏指的是不再使用的对象在系统中未被回收,内存泄漏的积累可能会导致内存溢出。手动回收的方式相对来说回收比较及时,删除代码执行之后对象就被回收了,可以快速释放内存。缺点是对程序员要求比较高,很容易出现创建完对象之后,程序员忘记释放对象。

2401_82540083的博客 2512

垃圾回收:垃圾回收器

垃圾收集器分类作用位置使用算法特点适用场景Serial串行运行作用于新生代复制算法响应速度优先适用于单CPU环境下的client模式ParNew并行运行作用于新生代复制算法响应速度优先多CPU环境Server模式下与CMS配合使用Parallel并行运行作用于新生代复制算法吞吐量优先适用于后台运算而不需要太多交互的场景Serial Old串行运行作用于老年代标记-压缩算法响应速度优先适用于单CPU环境下的Client模式并行运行作用于老年代。

学习总结 1527

垃圾回收算法和垃圾回收器

二万九千字,图文并茂解释垃圾回收算法和垃圾回收器,让你彻底理解垃圾回收算法和垃圾回收器

我是Java程序员廖志伟,感谢朋友们的支持! 1571

Java 垃圾回收

一般来说,Java开发人员大多关注业务逻辑的实现,但是,充分理解Java的 JVM中堆内存的分配和垃圾处理收集 这些内容可以让我们更有效地利用资源,更深刻的理解自己所写的代码。

码刀攻城 1413

JVM学习《垃圾回收算法和垃圾回收器》

因此就出现了一种标记-整理算法(Mark-Compact)算法,与标记-整理算法不同的是,在标记可回收的对象后将所有存活的对象压缩到内存的一端,使他们紧凑的排列在一起,然后对端边界以外的内存进行回收。重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录(主要 是处理漏标问题),这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记阶段时间短。垃圾收集时,遍历当前使用的区域,把存活对象复制到另外一个区域中,最后将当前使用的区域的可回收的对象进行回收。

GQ_666的博客 1631

JVM——垃圾回收

本文详细介绍了Java垃圾回收机制的核心概念和实现方法。首先,文章解释了如何判断对象可以回收,包括引用计数法和可达性分析算法,并介绍了四种引用类型:强引用、软引用、弱引用和虚引用。接着,文章探讨了三种垃圾回收算法:标记清除、标记整理和标记复制,并分析了它们的优缺点。随后,文章介绍了分代垃圾回收机制,将堆内存划分为新生代和老年代,并详细描述了MinorGC的流程。此外,文章还介绍了六种常见的垃圾回收器,包括串行、并行和并发的垃圾回收器,并重点分析了CMS和G1垃圾回收器的工作原理和优缺点。最后,文章提供了垃圾

2301_81283571的博客 1668

JVM垃圾回收

垃圾回收,回收算法,垃圾回收器,cms,serial new,serial old,parallel,GC日志

weixin_38612401的博客 4507

JVM垃圾回收算法及垃圾回收器

JVM基本垃圾回收算法,按照基本回收策略分 标记-清除(Mark-Sweep) 一、标记-清除(Mark-Sweep) https://www.html.cn/qa/other/22924.html 此算法执行分两阶段。 第一阶段 标记:遍历内存区域,对需要回收的对象打上标记。 第二阶段 清除:再次遍历内存,对已经标记过的内存进行回收。 此算法需要暂停整个应用 绿色、蓝色---代表存活对象 灰色---非存活对象 白色--未使用的内存 缺点: 效率问题:遍历了两次内存空间(

喵酱 2961

JVM虚拟机-垃圾回收(垃圾回收器、垃圾回收算法、分代回收、四大引用)

本文系统解析JVM垃圾回收机制,详解分代回收模型(新生代/老年代)、标记-清除/复制/整理算法原理,对比Serial、CMS、G1等回收器核心差异。结合强引用、软引用、弱引用、虚引用的应用场景与内存管理策略,探讨GC调优参数配置及内存泄漏排查思路,助力开发者理解回收逻辑,优化Java应用性能与稳定性。

Crayon26的博客 1153
上一篇: 迭代器
下一篇: Python的set集合
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值