java 管理对象是什么_Java工程师(16)对象的管理
包
包的創建規則
包可以有層次,在創建包時可以一次性創建多級包,上下級之間用“.”分割,如下圖所示。
訪問修飾符
簡介
訪問修飾符包括:private、protected、public。三者都可用于修飾成員變量、成員方法,從而影響成員變量、成員方法的訪問級別。
只有public可用于修飾類,從而影響類的訪問級別。
成員的訪問級別
成員變量、成員方法有4種訪問級別,它們與修飾符的關系見下表:
類的訪問級別
類有2種訪問級別,它們與修飾符的關系見下表:
垃圾回收
誰是垃圾
棧中數據會隨著方法調用的完成而出棧,不存在垃圾。堆中數據可以被棧引用,當棧中數據出棧后,引用將消失,此時堆中的數據沒有銷毀,就是垃圾。
清理垃圾、回收內存
所謂垃圾回收,是指清理堆中的垃圾數據,從而回收內存。Java的垃圾回收是自動進行的,即JVM會定時的掃描堆內存,完成垃圾清理的任務。開發者也可以通過調用“System.gc()”來催促JVM盡快進行垃圾回收,但不建議這樣做,因為這會打亂JVM的節奏,降低它的運行效率。
擴展閱讀:
GC(Garbage Collection)大部分人都把這項技術當做Java語言的伴生成物。事實上,GC的歷史要遠遠比Java久遠,1960年誕生于MIT的Lisp是第一門真正石永紅內存動態分配和垃圾收集技術的語言。當Lisp還在胚胎時期時,人們就在思考GC需要完成的三件事情:哪些內存需要回收?
什么時候回收?
如何回收?
經過半個多世紀的發展,內存的動態分配與內存回收技術已經相當成熟,一切看起來進入了“自動化”時代,那為什么我們還要去了解GC和內存分配呢?
答案:當需要排查各種內存溢出、內存泄露問題時,當垃圾收集器成為系統達到更高并發亮的瓶頸時,我們就需要對這些“自動化”的技術實施必要的監控和調節。
垃圾收集器在對堆進行回收前,第一件事就是要確定對象有哪些還“存活”著,哪些已經“死去”(即不可能再被任何途徑使用的對象)?
引用計數器算法
很多人在面試時的回答就是引用計數器算法,那么什么是引用計數器算法呢?
給對象添加一個引用計數器,每當有一個地方引用它時,計數器加1;當應用失效時計數器就減1;任何時刻計數器都為0的對象是不可能被使用的,就認定它時死的對象。
該算法實現簡單,判定效率也很高,在大多數情況下它是一個不錯的算法,比較著名的應用案例,如:微軟的COM(Component Object Model)技術、Python語言、Squireel。但是Java語言中沒有選用該算法,其中最主要的原因就是它很難解決對象之間的相互循環應用的問題。
舉例:
package com.jinxf;
public class ReferenceCountGC {
public Object instance = null;
private static final int _1MB = 1024*1024;
//這個成員屬性的唯一意義就是占點內存,以便能在GC日志中看清楚是否被回收過 private byte[] bigSize = new byte[2*_1MB];
public static void main(String args[]){
ReferenceCountGC objA = new ReferenceCountGC();
ReferenceCountGC objB = new ReferenceCountGC();
objA.instance = objB;
objB.instance = objA;
objA = null;
objB = null;
//假設在這行放生GC,那么objA和objB是否能被回收? System.gc();
}
}
main方法:對象objA和objB都有字段instance,通過該字段讓他們兩個互相引用,然后將他們兩個置為null不可能再被訪問,但是他們因為互相引用著對象,導致它們的引用計數器都不為0,于是引用計數算法無法通知GC收集器收集它們。
com.jinxf.ReferenceCountGC
[GC (System.gc()) [PSYoungGen: 9359K->936K(153088K)] 9359K->944K(502784K), 0.0007702 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 936K->0K(153088K)] [ParOldGen: 8K->699K(349696K)] 944K->699K(502784K), [Metaspace: 3337K->3337K(1056768K)], 0.0038525 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
PSYoungGen total 153088K, used 3947K [0x0000000715c00000, 0x0000000720680000, 0x00000007c0000000)
eden space 131584K, 3% used [0x0000000715c00000,0x0000000715fdafd8,0x000000071dc80000)
from space 21504K, 0% used [0x000000071dc80000,0x000000071dc80000,0x000000071f180000)
to space 21504K, 0% used [0x000000071f180000,0x000000071f180000,0x0000000720680000)
ParOldGen total 349696K, used 699K [0x00000005c1400000, 0x00000005d6980000, 0x0000000715c00000)
object space 349696K, 0% used [0x00000005c1400000,0x00000005c14aec08,0x00000005d6980000)
Metaspace used 3350K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 365K, capacity 388K, committed 512K, reserved 1048576K
Process finished with exit code 0
說明:
GC開頭的說明此次垃圾回收為Minor GC,而Full GC開頭的說明此次垃圾回收為stop-the-world的類型
PSYoungGen表示年輕代,ParOldGen表示老年代
方括號內的"9359K->936K(153088K)]“表示"GC前該內存區域已使用容量->GC后該內存區域已使用容量(該內存區域總容量)”
方括號外的"9359K->944K(502784K)“表示"GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆總容量)”
“0.0009304 secs"表示該內存區域本次GC所占用的時間,單位是秒。有的收集器會給出更具體的時間數據,如”[Time:user=0.01 sys=0.01 real=0.02 secs]",這里的user、sys、real與Linux的time命令所輸出的時間含義一致,分別代表用戶態消耗的CPU時間、內核態消耗的CPU時間、操作從開始到結束所經過的墻鐘時間。CPU時間和墻鐘時間的區別是,墻鐘時間包括各種非運算的等待耗時,如等待磁盤I/O、等待線程阻塞,而CPU時間不包括這些耗時,但當系統有多CPU或者多核的話,多線程操作會疊加這些CPU時間,所以若看到user或sys時間超過real時間也是完全正常的。
eden、from、to表示年輕代中各區域的劃分
Metaspace表示元空間的大小,這里用的是JDK1.8,如果是JDK1.7則沒有該區域
但是從GC日志中得出虛擬機并沒有因為這兩個對象相互引用就不回收他們,這也從側面上說明虛擬機并不是通過引用計數算法來判斷對象是否存活的。
根搜索算法
Java、C#、Lisp都是使用根搜索算法(GC Roots Tracing)判定對象是否存活的。該算法的思路是通過一系列的名為“GC Roots”的對象作為起始點,從這些節點開始向下搜索,搜索所走過的路徑成為引用鏈(Reference Chain),當一個對象到GC Roots沒有任何引用鏈相連(用圖論的話來說就是從GC Roots到這個對象不可達)時,則證明此對象是不可用的。
如下圖所示,對象object5、object6、object7雖然互相有關聯,但是他們到GC Roots是不可達的,所以它們將會被判定為是可回收的對象。
Java語言里,可作為GC Roots的對象包括下面幾種:虛擬機棧(棧幀中的本地變量表)中的引用對象
方法區中的類靜態屬性引用的對象。
方法區中常量引用的對象
本地方法棧中JNI(即一般說Native方法)的引用的對象
作業創建名為“com.jinxf.hello”的包,然后去workspace下找到這個項目,觀察src和bin下面的目錄結構。
2.在Eclipse中導入老師上課所寫的“成員的訪問級別示例”項目。在Demo類的main方法中,調用“v.”,觀察彈出窗口中所能訪問到的Vehicle對象的內容。
在Car類的test方法中,調用“super.”,觀察彈出窗口中所能訪問到的父類的內容。
在Test類的main方法中,調用“v.”,觀察彈出窗口中所能訪問到的Vehicle對象的內容。
總結
以上是生活随笔為你收集整理的java 管理对象是什么_Java工程师(16)对象的管理的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: java udp 缓冲区_为什么特定的U
- 下一篇: Jdbc访问mysql查询聚合函数_JD
