python程序如何执行死刑图片_如何判断对象已死
已死的對象就是不可能被任何途徑使用的對象,有以下幾種方法判斷一個對象是否已經死了:
引用計數
給對象添加一個引用計數器,每當有一個地方引用他,計算器就加 1;當引用失效時,計數器減 1;任何時刻計數器為 0 的對象就是死的對象。
1. 這種方式被很多技術所采用,如 FlashPlayer(AS3)、Python 等,但是 Java 沒有采用這種算法,原因是它很難解決對象之間相互循環引用的問題,例如 ObjectA.param=ObjectB,ObjectB.param=ObjectA,對象 A 和 B 相互引用但是除此之外他們再無任何其他引用,這樣他們的引用計數都不為 0,永遠不會被回收
根搜索
Java 采用的是根搜索算法,這個算法的基本思路是通過一系列名為“GC Roots”的對象作為起始點,從這些節點開始向下搜索,搜索所經過的路徑稱為引用鏈,當 GC Roots 到一個對象不可達時,這個對象就是不可用的
1. Java 中可作為 GC Roots 的對象包括:
1)虛擬機棧中引用的對象
2)方法區中類靜態屬性和常量引用的對象
3)本地方法棧中 Native 方法引用的對象
何為引用(和 ROOT 有關系)
簡單描述引用就是一塊內存中存儲的數值代表的是另外一塊內存的起始地址,則成這塊內存代表著一個引用,這種描述很純粹但是是不太正確的,可以作為理解時用
1. 引用分為強引用、軟引用、弱引用、虛引用
1)強引用:如 Object obj=new Object();只要強引用存在,GC 肯定不會回收被引用的對象
2)軟引用:非必需的對象,當系統要發生內存溢出之前,會把這些對象列入回收范圍
3)弱引用:更加非必需的對象,弱引用關聯的對象只能生存到下一次垃圾回收之前
4)虛引用:也叫幽靈引用或者幻影引用,它是最弱的一種引用,虛引用不會引用一個對象的生命周期,也無法通過一個虛引用獲取一個對象實例,只是虛引用的對象被回收時會有一個通知返回回去
兩次標記——死刑
一個對象在進行根搜索后發現沒有與 GC Roots 相關聯的引用鏈(和皇帝沒有關系),那么它將被第一次標記并且進行一次判斷,判斷該對象是否覆蓋了 finalize 方法(被下了死刑),如果是的,則認為有必要執行回收(死刑),如果不是則判斷 finalize 方法是否已經被虛擬機調用過,如果已經調用過了,則認為沒必要執行了(因為已經執行過死刑了)
如果一個對象被判定為執行死刑,那么這個對象將會被放置在一個名為 F-Queue 的隊列中(關起來了),這個隊列會在另外一條線程中執行死刑,因為隊列中的對象可能存在死循環等情況(危險分子),在 GC 主線程中執行可能導致整個 GC 崩潰
稍后 GC 便會新開一條線程來執行死刑,它先對 F-Queue 中的對象進行第二次標記,這時如果隊列中有個對象與引用鏈上任何一個對象建立關聯(有人給你喊刀下留人),那么在這次標記中它將會被移出 F-Queue,不然就死了
永久代就不會被殺嗎
JVM 規范中說過方法區(永久代)可以不實現垃圾回收,但是被上了免死金牌的永久代也是可以殺的,只是殺的少些而已,不像新生代,一次垃圾收集就可以殺掉 70%~95% 的對象
1. 永久代回收只要針對兩部分內容:廢棄常量和無用的類
1)回收廢棄常量例子:一個字符串“abc”已經進入了常量池中,但是當前系統沒有任何一個 String 對象叫做“abc”,而且如果必要的話(沒內存啦),那么這個對象將會被請出常量池(朝廷沒錢了,就不給一些朝中無人的王爺發錢了,自己過日子去)
2)判斷一個類似“無用的類”
·該類所有的實例都被殺掉
·加載該類的 ClassLoader 已經被殺掉
·該類的 Class 對象沒有在任何地方被引用,沒有在任何地方通過反射訪問該類地方法
滿足這三個條件也并不是一定要殺掉,詳見類卸載,主要在經常要大量使用反射、CGLib、動態代理、動態生成 JSP、OSGI 等場景需要配置下,以保證永久代不會溢出
一個例子
問題:下面代碼中,第幾行的哪個對象符合垃圾回收標準?
1 Object a = new Object();
2 Object b = new Object();
3 Object c = new Object();
4 a = b;
5 a = c;
6 c = null;
7 a = null;
答案:直到第 7 行時才有一個對象 c 符合了垃圾回收標準
總結
以上是生活随笔為你收集整理的python程序如何执行死刑图片_如何判断对象已死的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国刀具行业投资分析
- 下一篇: 2022-2028年中国高强度钢行业投资