什么是python语言的动态类型机制_python的内存管理机制
一、python是一個什么樣類型的語言
1、python是一種動態(tài)解釋性強(qiáng)類型定義的高級、通用性編程語言。
解釋型:執(zhí)行的時候,才一條一條的解釋成機(jī)器語言給計算機(jī)來執(zhí)行。如:python、js、ruby、PHP等
編譯型:把源程序的每一條語句都編譯成機(jī)器語言,并保存成二進(jìn)制文件,這樣運行時計算機(jī)可以直接以機(jī)器語言來運行此程序,速度快。如:C、C++、go等
動態(tài)語言:動態(tài)類型的語言編程時,永遠(yuǎn)也不用給任何變量指定數(shù)據(jù)類型,該語言會在你第一次賦值給變量時,在內(nèi)部將數(shù)據(jù)類型記錄下來
靜態(tài)語言:與動態(tài)類型語言剛好相反,它的數(shù)據(jù)類型是在編譯其間檢查的,也就是說在寫程序時要聲明所有變量的數(shù)據(jù)類型
強(qiáng)類型定義語言:一旦一個變量被指定了某個數(shù)據(jù)類型,如果不經(jīng)過強(qiáng)制轉(zhuǎn)換,那么它就永遠(yuǎn)是這個數(shù)據(jù)類型
弱類型定義語言:數(shù)據(jù)類型可以被忽略的語言。它與強(qiáng)類型定義語言相反, 一個變量可以賦不同數(shù)據(jù)類型的值
二、python的內(nèi)存管理機(jī)制
python的內(nèi)存管理機(jī)制:引用計數(shù)、垃圾回收、內(nèi)存池機(jī)制
1、變量與對象
1、變量:通過變量指針引用對象
變量指針:指向具體對象的內(nèi)存空間,取對象的值。
2、對象,類型已知,每個對象都包含一個頭部信息(頭部信息:類型標(biāo)識符和引用計數(shù)器)
注意:變量名沒有類型,類型屬于對象(因為變量引用對象,所以類型隨對象),變量引用什么類型的對象,變量就是什么類型的。
a、容器對象
Python的一個容器對象(比如:表、詞典等),可以包含多個對象。
容器對象:容器對象中包含的并不是元素對象本身,是指向各個元素對象的引用。
1、Python緩存了整數(shù)和短字符串,因此每個對象在內(nèi)存中只存有一份,引用所指對象就是相同的,即使使用賦值語句,也只是創(chuàng)造新的引用,而不是對象本身;
2、Python沒有緩存長字符串、列表及其他對象,可以有多個相同的對象,可以使用賦值語句創(chuàng)建出新的對象。
2、引用計數(shù)
a、普通引用
注意:當(dāng)使用某個引用作為參數(shù),傳遞給getrefcount()時,參數(shù)實際上創(chuàng)建了一個臨時的引用。因此,getrefcount()所得到的結(jié)果,會比期望的多1。
b、容器對象
c、引用計數(shù)增加
1、對象被創(chuàng)建
2、另外的別人被創(chuàng)建
3、作為容器對象的一個元素
d、引用計數(shù)減少
1、對象的別名被顯式的銷毀
2、對象的一個別名被賦值給其他對象
3、對象從一個窗口對象中移除,或,窗口對象本身被銷毀
4、一個本地引用離開了它的作用域,比如上面的foo(x)函數(shù)結(jié)束時,x指向的對象引用減1。
3、垃圾回收
吃太多,總會變胖,Python也是這樣。當(dāng)Python中的對象越來越多,它們將占據(jù)越來越大的內(nèi)存。不過你
不用太擔(dān)心Python的體形,它會乖巧的在適當(dāng)?shù)臅r候“減肥”,啟動垃圾回收(garbage collection),將沒用的
對象清除。在許多語言中都有垃圾回收機(jī)制,比如Java和Ruby。盡管最終目的都是塑造苗條的提醒,但不同
語言的減肥方案有很大的差異 (這一點可以對比本文和Java內(nèi)存管理與垃圾回收)。
從基本原理上,當(dāng)Python的某個對象的引用計數(shù)降為0時,說明沒有任何引用指向該對象,該對象就成為要被
回收的垃圾了。比如某個新建對象,它被分配給某個引用,對象的引用計數(shù)變?yōu)?。如果引用被刪除,對象的引
用計數(shù)為0,那么該對象就可以被垃圾回收。比如下面的表:
a =[1,2,3]
dela
del a后,已經(jīng)沒有任何引用指向之前建立的[1, 2, 3]這個表。用戶不可能通過任何方式接觸或者動用這個對象。
這個對象如果繼續(xù)待在內(nèi)存里,就成了不健康的脂肪。當(dāng)垃圾回收啟動時,Python掃描到這個引用計數(shù)為0的對象,
就將它所占據(jù)的內(nèi)存清空。
然而,減肥是個昂貴而費力的事情。垃圾回收時,Python不能進(jìn)行其它的任務(wù)。頻繁的垃圾回收將大大降低Python的
工作效率。如果內(nèi)存中的對象不多,就沒有必要總啟動垃圾回收。所以,Python只會在特定條件下,自動啟動垃圾回收。
當(dāng)Python運行時,會記錄其中分配對象(object allocation)和取消分配對象(object deallocation)的次數(shù)。當(dāng)兩者的差值高于
某個閾值時,垃圾回收才會啟動。
我們可以通過gc模塊的get_threshold()方法,查看該閾值:
importgc
print(gc.get_threshold())
返回(700, 10, 10),后面的兩個10是與分代回收相關(guān)的閾值,后面可以看到。700即是垃圾回收啟動的閾值。可以
通過gc中的set_threshold()方法重新設(shè)置。
我們也可以手動啟動垃圾回收,即使用gc.collect()。
分代回收
Python同時采用了分代(generation)回收的策略。這一策略的基本假設(shè)是,存活時間越久的對象,越不可能在
后面的程序中變成垃圾。我們的程序往往會產(chǎn)生大量的對象,許多對象很快產(chǎn)生和消失,但也有一些對象長期被使用。
出于信任和效率,對于這樣一些“長壽”對象,我們相信它們的用處,所以減少在垃圾回收中掃描它們的頻率。
Python將所有的對象分為0,1,2三代。所有的新建對象都是0代對象。當(dāng)某一代對象經(jīng)歷過垃圾回收,依然存活,那么它就
被歸入下一代對象。垃圾回收啟動時,一定會掃描所有的0代對象。如果0代經(jīng)過一定次數(shù)垃圾回收,那么就啟動對0代和1代的
掃描清理。當(dāng)1代也經(jīng)歷了一定次數(shù)的垃圾回收后,那么會啟動對0,1,2,即對所有對象進(jìn)行掃描。
這兩個次數(shù)即上面get_threshold()返回的(700, 10, 10)返回的兩個10。也就是說,每10次0代垃圾回收,會配合1次1代的垃圾
回收;而每10次1代的垃圾回收,才會有1次的2代垃圾回收。
同樣可以用set_threshold()來調(diào)整,比如對2代對象進(jìn)行更頻繁的掃描。
importgc
gc.set_threshold(700,10,5)
4、內(nèi)存池機(jī)制
Python中有分為大內(nèi)存和小內(nèi)存:(256K為界限分大小內(nèi)存)
1、大內(nèi)存使用malloc進(jìn)行分配
2、小內(nèi)存使用內(nèi)存池進(jìn)行分配
3、Python的內(nèi)存池(金字塔)
第3層:最上層,用戶對Python對象的直接操作
第1層和第2層:內(nèi)存池,有Python的接口函數(shù)PyMem_Malloc實現(xiàn)-----若請求分配的內(nèi)存在1~256字節(jié)之間就
使用內(nèi)存池管理系統(tǒng)進(jìn)行分配,調(diào)用malloc函數(shù)分配內(nèi)存,但是每次只會分配一塊大小為256K的大塊內(nèi)存,不會
調(diào)用free函數(shù)釋放內(nèi)存,將該內(nèi)存塊留在內(nèi)存池中以便下次使用。
第0層:大內(nèi)存-----若請求分配的內(nèi)存大于256K,malloc函數(shù)分配內(nèi)存,free函數(shù)釋放內(nèi)存。
第-1,-2層:操作系統(tǒng)進(jìn)行操作
內(nèi)容來自:
原文地址:https://www.cnblogs.com/youhongliang/p/12207714.html
總結(jié)
以上是生活随笔為你收集整理的什么是python语言的动态类型机制_python的内存管理机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求回答,柏尔定制地板怎么样?
- 下一篇: 租房加固话需要去公安局备案吗