gj7 对象引用、可变性和垃圾回收

7.1 python变量到底是什么

#python和java中的变量本质不一样,python的变量实质上是一个指针 int str, 便利贴

a = 1
a = "abc"
#1. a贴在1上面
#2. 先生成对象 然后贴便利贴

a = [1,2,3]
b = a
print (id(a), id(b))
print (a is b)
b.append(4)
print (a)

---
1642030876232 1642030876232
True
[1, 2, 3, 4]

7.2 ==和is的区别

is 判断是否是同一个对象,id是否相等

a = [1,2,3,4]
b = [1,2,3,4]

print(a == b)  # 判断值是否相等
print (id(a), id(b))
print (a is b)

c=1
d=1
print(c is d)  # 将一定范围的小整数,内存地址进行了复用
 
# ---
True
1642030933512 1642030785544
False
True

---

class People:
    pass

person = People()
if type(person) is People:
    print ("yes")

type(person)

---
yes
__main__.People

7.3 del语句和垃圾回收

# cpython中垃圾回收的算法是采用 引用计数
# 当计数器减为0 就会被回收
a = object()
b = a
del a
print(b)
print(a)

class A:
    def __del__(self):   # 当被回收的时候,执行下面的逻辑
        pass

7.4 一个经典的错误

为了数据的安全性,使用tuple而不是list类型来存储

def add(a, b):
    a += b
    return a
a = 1
b = 2
c = add(a,b)
print(c)
print(a,b)
# ---
3
1 2
# ---传递进来的list受到了影响
a = [1,2]
b = [3,4]
c = add(a,b)
print(c)
print(a,b)
# ---
[1, 2, 3, 4]
[1, 2, 3, 4] [3, 4]
# ---
a = (1,2)
b = (3,4)
c = add(a,b)
print(c)
print(a,b)
---
(1, 2, 3, 4)
(1, 2) (3, 4)

---
 
class Company:
    def __init__(self, name, staffs=[]):
        self.name = name
        self.staffs = staffs
    def add(self, staff_name):
        self.staffs.append(staff_name)
    def remove(self, staff_name):
        self.staffs.remove(staff_name)

com1 = Company("com1", ["lewen1", "lewen2"])
com1.add("lewen3")
com1.remove("lewen1")
print("com1.staffs:",com1.staffs)

com2 = Company("com2") # 使用了默认的[],list又是可变的对象
com2.add("lewen")
print(com2.staffs)

print (Company.__init__.__defaults__) # 没有传递参数时,都使用默认的【】值

com3 = Company("com3")   # 使用了默认的[],list又是可变的对象
com3.add("lewen5")
print (com2.staffs)
print (com3.staffs)
print (com2.staffs is com3.staffs)
# ---
com1.staffs: [‘lewen2‘, ‘lewen3‘]
[‘lewen‘, ‘lewen5‘, ‘lewen‘, ‘lewen5‘, ‘lewen‘, ‘lewen5‘, ‘lewen‘]
([‘lewen‘, ‘lewen5‘, ‘lewen‘, ‘lewen5‘, ‘lewen‘, ‘lewen5‘, ‘lewen‘],)
[‘lewen‘, ‘lewen5‘, ‘lewen‘, ‘lewen5‘, ‘lewen‘, ‘lewen5‘, ‘lewen‘, ‘lewen5‘]
[‘lewen‘, ‘lewen5‘, ‘lewen‘, ‘lewen5‘, ‘lewen‘, ‘lewen5‘, ‘lewen‘, ‘lewen5‘]
True

-

原文地址:https://www.cnblogs.com/wenyule/p/10363581.html

时间: 2024-08-01 00:25:56

gj7 对象引用、可变性和垃圾回收的相关文章

对象引用、可变性和垃圾回收

1.python中变量是什么? 在数学概念中,变量表示没有固定值且可以改变的数值.在计算机系统中,变量表示一段或者多段用来存储数据的内存.变量名都是指代的一个指针. 在GO语言里面,变量总是有固定的类型,变量类型决定了数据在内存中的长度存储格式. 在python中,变量进行初始化的时候可以不指定类型,那它是如何存储的?你可以将变量看成标签,比如a = 1现在将a这个便签绑定在1这个int类型的对象上面.a = “kebi”现在又将a重新绑定在”kebi“这个str类型的对象上面.这种操作只能在动

第七章python对象引用、可变性和垃圾回收

1.python变量是什么 python的变量实质是一个指针,而java普通变量是一个容器直接存入值. 为什么b也变了呢,由于a,b同时指向同一个地址,导致a指向的内容改变也会让b改变,id()获得对象所指向的内存中的地址,如果是对象本身的地址的话a,b应该是不相同的. 1 a = [1, 2, 3] 2 b = a 3 # a和b实质是指针都指向同一个地址,修改a同时会修改b 4 print(id(a), id(b)) # 54866344 54866344 5 print(a is b) #

JavaGC专家(1)—深入浅出Java垃圾回收机制

在学习GC之前,你首先应该记住一个单词:"stop-the-world".Stop-the-world会在任何一种GC算法中发生.Stop-the-world意味着 JVM 因为要执行GC而停止了应用程序的执行.当Stop-the-world发生时,除了GC所需的线程以外,所有线程都处于等待状态,直到GC任务完成.GC优化很多时候就是指减少Stop-the-world发生的时间. 按代的垃圾回收机制 在Java程序中不能显式地分配和注销内存.有些人把相关的对象设置为null或者调用Sy

CMS垃圾回收机制

详解CMS垃圾回收机制 原创不易,未经允许,不得转载~~~ 什么是CMS? Concurrent Mark Sweep. 看名字就知道,CMS是一款并发.使用标记-清除算法的gc. CMS是针对老年代进行回收的GC. CMS有什么用? CMS以获取最小停顿时间为目的. 在一些对响应时间有很高要求的应用或网站中,用户程序不能有长时间的停顿,CMS 可以用于此场景. CMS如何执行?  总体来说CMS的执行过程可以分为以下几个阶段: 3.1 初始标记(STW) 3.2 并发标记 3.3 并发预清理

JVM那些事儿(二)——垃圾回收

这节小汪介绍一下jvm的垃圾回收机制,首先我们先提问: 1.为什么要有不同的垃圾算法 2.垃圾回收器要解决的终极目的是什么 3.小汪该如何选择自己的垃圾回收器 一.垃圾回收算法 众所周知,java堆内存的垃圾回收由java虚拟机管理,目前java有几种算法用来解决垃圾回收(以下只介绍最重要的两个算法) 1.1 复制算法 如图所示,复制算法可以说是最直观最简洁的算法了.按照复制算法的思路,内存要分为两块 Eden Survivor区域,Eden有一个,Survivor有两个. 首先,各种对象都在E

深入理解JAVA虚拟机之JVM性能篇---垃圾回收

一.基本垃圾回收算法 1. 按基本回收策略分 1) 引用计数(Reference Counting)  对象增加一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最致命的是无法处理循环引用的问题. 2)标记-清除(Mark-Sweep)  执行分两阶段.第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除. 缺点是此算法需要暂停整个应用,同时会产生内存碎片. 3)复制(Copying) 把内存空间划为两个相等的区域,每

各种垃圾回收 (转)

1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息",这些信息将被丢弃.当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用.事实上,除了释放没用的对象,垃圾回收也可以清除内存记录碎片.由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,

Java内存分配与垃圾回收

1.JVM管理的内存包含下图所示的几个运行时数据区域,其中方法区和堆为线程共享的数据区域,程序计数器,虚拟机栈以及本地方法栈为线程私有的数据区域. 程序计数器:可以看做是当前线程所执行的字节码的行号指示器,告诉字节码解释器该读取哪条指令 虚拟机栈:生命周期和线程相同,每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息,每一个方法从调用到完成的过程就对应了一个栈帧在虚拟机中入栈到出栈的过程.栈中存放了编译器可知的各种基本数据类型和对象引用. 本地方法栈:与

【JVM】JVM系列之垃圾回收(二)

一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收.除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此.所以,垃圾回收是必须的. 二.哪些内存需要进行垃圾回收 对于虚拟机中线程私有的区域,如程序计数器.虚拟机栈.本地方法栈都不需要进行垃圾回收,因为它们是自动进行的,随着线程的消亡而消亡,不需要我们去回收,比如栈的栈帧结构,当进入一个方法时,就会产生一个栈帧,栈帧大小也可以借助类信息确定,然后栈帧入栈,执行方法体,退出方法时,栈帧出