zoukankan      html  css  js  c++  java
  • python进阶之内存模型

     

     

    每一个编程语言的背后都有自己独特的内存模型支持,比如最经典的C语言,一个int类型占8字节。那么在python中不区分数据类型,定义一个变量其在内存在占用多少字节呢?python中数据的运算其内存是如何变化的呢?

    在回答上面的问题之前,首先看一下python中可变的数据和不可变数据


    一、可变对象和不可变对象

    Python一切数据皆为对象,python中的对象分成两类:可变对象和不可变对象。所谓可变对象是指,对象的内容可变,而不可变对象是指对象内容不可变。

    不可变(immutable):数值(int、float)、字符串(string)、元组(tuple)

    可变(mutable):字典型(dictionary)、列表型(list) 

     

    根据对象的分类,可以将数据类型也做一个分类,可变数据类型与不可变数据类型:

    可变数据类型:列表list和字典dict 

    不可变数据类型:整型int、浮点型float、字符串型string和元组tuple 

      

    这里的可变不可变,是指内存中的那块内容是否可以被改变。

    如果是不可变类型,在对对象本身操作的时候,必须在内存中新申请一块区域(因为老区域不可变)。创建a=1整型对象,执行a=2时,内存中的对象1是不变的,只是重新创建了对象2。

    如果是可变类型,对对象操作的时候,不需要再在其他地方申请内存,只需要在此对象后面连续申请(+/-)即可,也就是它的内存地址会保持不变,但区域会变长或者变短。

     

    当对可变和不可变对象运算时会内存中会发生什么事情呢?对比来看

    不可变数据类型:不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象; 
    可变数据类型:允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。

     

    python对于数据的特殊处理 

     

    小整数

    Python为了优化速度,避免为整数频繁申请和销毁内存空间,使用了小整数对象池。对小整数的定义是 [-5, 256] 这些整数对象是提前建立好的,不会被垃圾回收。在这个范围内所有的整数都只会被建立一次。

    a = 100
    b = 100
    print(id(a))
    print(id(b))
    
    -------------------------
    94125443429088
    94125443429088

      

    a = 200
    b = 200 
    
    print a is b 
    -----------------
    True
    
    
    a = 300
    b = 300
    print a is b
    -----------------
    False

    大整数

    大整数池: 只存储包含标准字符(数字、字母、下划线)的字符串,不包含特殊字符的字符串 。

    python为了避免创建大整数浪费的内存空间和时间,将创建过的大整数加入大整数池。

    python中大整数池,默认大整数池里面为空,每一个py程序都有一个大整数池。使用大整数时如果大整数池里不存在该整数的话,会新建一个大整数对象。下次使用大整数时直接使用大整数池里的对象,而不是创建新的对象 

    py文件中,每次运行时都会将所有代码加载到内存中,属于一个整体,因此处于同一个代码块的大整数是同一个对象,所以两者id是一样的。

    a = '12345'
    b = '12345'
    
    print id(a)
    print id(b)
    -----------------------------
    140139908067808
    140139908067808
    
    
    print a is b
    -----------------------------
    True

    其他数据类型

    如果是其他普通类型对象的新建,python会请求内存,申请内存 。当n1的引用指向其他对象时,原有对象的引用计数会自动减1,没有被引用的对象会立即回收。

     

  • 相关阅读:
    第五章 并发性:互斥和同步
    第四章 线程、SMP和微内核
    Python Linked List
    关于名字查找
    测试当前C环境的栈帧增长方向以及传递参数时的压栈顺序
    关于栈——不针对特定实现的分析
    c语言15行实现简易cat命令
    C11 constant expressions 常量表达式
    一个fork短码的扩展版本
    为什么C++没有对应realloc的new操作符呢?
  • 原文地址:https://www.cnblogs.com/goldsunshine/p/11502468.html
Copyright © 2011-2022 走看看