Java Garbage Collection筆記

Monday, October 22, 2007

這是前陣子對公司內部分享gc觀念的筆記,放上來留個紀錄。


JVM使用的記憶體

Java Heap


1. Java 程式執行時,JVM 用來配置Java objects 的記憶體
2. GC 發生作用的記憶體
3. 預設值 (僅供參考)
*Xms大約都是4MB
*Xmx
1.AIX 為64MB
2.Windows 為實體記憶體的二分之一(16MB ~ 2GB -1)
3.Linux 為實體記憶體的二分之一(16MB ~ 512MB -1)

Native Heap

1. JVM 用來它內部運作的記憶體
2. JNI: Third party 的native module
3. 大小取決於產生的程式碼、產生的thread、GC 時用於保存javaobject 資訊
與產生或最佳化程式碼時的暫存空間
4. 預設值 (僅供參考) *128K(會隨著需求往上增長)

GC三部曲

1. Mark Phase
* 搜尋Java Heap 內全部的物件,找出已經沒有在使用中的物件
2. Sweep Phase
* 將無用的物件清除
3. Compaction Phase(optional)
*搬動物件,壓實Java Heap ,藉以移除物件之間的空白空間
*有些物件是無法搬動 Pinned (pointer 來自JNI, thread) , Dosed (pointer 來自stack)

GC的天時地利

* 當物件實體(Instance)沒有被參考時, 才允許被回收

* 參閱圖1範例判斷物件A~E,變成允許回收的順序 (A→B 為B被A所參考)
* 範例程式碼
     1: public void method1(){
2: Myclass a = new Myclass();
3: a = null; //步驟2產生的物件可以被gc

4: java.util.Date d = new java.util.Date();
5: d = new java.util.Date( long_date ); //步驟4產生的物件可以被gc
6: } //步驟5產生的物件可以被gc


*下面程式碼中A B C變成允許回收的順序?
     class OBJ{
private static A a = new A();
public B b = new B();

public void method1(){
C c = new C();
}
}


* 只能建議GC時機,但實際執行由JVM決定. 建議JVM執行GC方式如下
1. System.gc()
2. Runtime.getRuntime().gc()

* finalize()
1. finalize方法位於Java.Object
2. 當物件被JVM回收時會呼叫
3. 一般可用來手動釋放資源

練習

*Case 1 請問步驟8時,步驟1和2產生的物件是否允許被回收?

1: A a = new A;
2: A b = new A;
3: A c=b;

4: b=a;
5: a=null;
6: a=c;
7: b=null;

8: c=null;
9: ......


*Case 2 請問步驟4所產生的object何時允許被回收?

1. public class Test {
2. private Demo d;
3. void start() {
4. d = new Demo();
5. this.takeDemo(d) ;
6. }
7.
8. void takeDemo(Demo demo) {
9. demo = null;
10. demo = new Demo();
11. }
12. public static void main(String[] arg){
13. Test test = new Test();
14. test.start();
15. test.start();
16. }
17.}


* Case 3 下列程式碼為圖1的實作,執行結果為何?


import java.util.ArrayList;
public class TestOBJ {
private String name;
private ArrayList
referenceList = new ArrayList();

public TestOBJ(String name){
this.name = name;
}

public String getName(){
return name;
}

public void reference(TestOBJ obj){
referenceList.add(obj);
System.out.println(name + " -> "+obj.getName());
}

protected void finalize() throws Throwable {
System.out.println(name + " got gc.");
super.finalize();
}

public static void main(String[] arg){
TestOBJ a = new TestOBJ("A");
TestOBJ b = new TestOBJ("B");
TestOBJ c = new TestOBJ("C");
TestOBJ d = new TestOBJ("D");
TestOBJ e = new TestOBJ("E");
TestOBJ f = new TestOBJ("F");
a.reference(b);
b.reference(c);
b.reference(d);
d.reference(e);
d.reference(f);
f.reference(c);
c.reference(e);
System.out.println("==========="); //分隔線

a = null;
b = null;
c = null;
d = null;
e = null;
f = null;
System.gc(); //假設jvm執行gc
}
}


JMF ChannelEffect

Tuesday, October 9, 2007

In past month, I tried to use java to write a karaoke software.
But I met some problem.
The MpegParser is not stable.When I used a Processor to play mpeg file.
I got some problems.
I thought it's too difficult for me to solve those problem. So I gave up.

I also saw JMF can't control the mpg sound channel.
I thought MpegAudioControl have never been implemented.
So I refer to the GainEffect to write a simple effect.
It can output mono sound in right channel or left channel.
Maybe it can help someone.


public int process(Buffer inputBuffer, Buffer outputBuffer){

byte[] inData = (byte[])inputBuffer.getData();
int inLength = inputBuffer.getLength();
int inOffset = inputBuffer.getOffset();

byte[] outData = validateByteArraySize(outputBuffer, inLength);

int outOffset = outputBuffer.getOffset();
int j = outOffset;
int outLength = inLength;

int samplesNumber = inLength / 4 ;

if(isRight){ //true for right channel
inOffset+=2;
}
for (int i=0; i< samplesNumber;i++) {
outData[j ++]=(byte) (inData[inOffset ++] & 0xff);
outData[j ++]=(byte) (inData[inOffset ++] & 0xff);
outData[j ++]=(byte) (inData[(inOffset-2)] & 0xff);
outData[j ++]=(byte) (inData[(inOffset-1)] & 0xff);
inOffset+=2;
}
outputBuffer.setFormat(outputFormat);
outputBuffer.setLength(outLength);
outputBuffer.setOffset(outOffset);
return BUFFER_PROCESSED_OK;
}
ChannelEffect.java

Wow! Passed SCEA!

Monday, October 8, 2007

Yes, I have passed SCEA!
I am from Taiwan. I am not a native English speaker.
I think language hinder me from reading assignment.

-----------------------------------------------------------
Part I (310-051)
Grade: P
Scroe: 91
-----------------------------------------------------------
Part II (310-061)
Grade: P
Score: 90
Class Diagram ..................... 39/44
Component Diagram ................ 39/44
Sequence Diagrams................. 12/12
-------------------------------------------------------------


My assignment had the following diagrams.
Class diagram:
One diagram had 18 classes without attributes,methods & stereotypes.
I just extend the business object model.

Component diagram:
One diagram had 27 components.

Sequence diagram:
Five diagrams.
I separate pay itinerary into two diagrams(credit card & award)

My deliverable document have 7 pages(include diagrams).

My suggestion:

In part I...
Read hard and do mock exams as more as you can.
It's not a big problem to pass.

In part II...
Read the assignment again and again and read the posts in javaranch more and more.
Until you can explain the assignment completely in your mind.
Of course, sometimes you need to make some assumptions.
Don't draw too much things on your diagrams.
Keep it simple and clear.

In part III...
Before taking exam, I worried that I can't express well in English.
Now I'll tell you it's easy. If you design part 2, you can handle part 3.

Lazy Loading Singletons新寫法

Sunday, July 29, 2007

在Bob Lee的blog中,看到Lazy Loading Singletons新寫法
很特別的一個寫法,不但code比較簡潔而且效率還比較好

static class SingletonHolder {
static Singleton instance = new Singleton();
}

public static Singleton getInstance() {
return SingletonHolder.instance;
}


詳細請參閱 crazybob.org: Lazy Loading Singletons

java面試題

今天主管拿了一份java試題給我做 ,真的難倒我了...
上了google打了關鍵字 ,發現網路上已經有人po出答案了...
總覺得網路上的答案和我想的有出路,這是我的答案..
不知道哪裡有正確答案....有人要給我正確答案嗎?


第一,談談final, finally, finalize的區別。

這三個沒什麼關係。
final是修飾的關鍵字,可修飾類別、方法 和變數。
final class該類別無法被繼承,final method 該方法不能被override,final variable
該變數一經設定後就無法修改。

finally 在例外處理中(try…catch….finally)最後一定會被執行的區塊。

finalize 當 garbage collector發現某物件已經不被任何物件所參考(reference)

會呼叫該物件的finalize(),finalize()內沒有什特別的動作一般會被

OVERRIDE拿來作為資源的釋放。


第二,Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其他類,是否可以implements(實現)interface(介面)?

可以,但不能同時extends和implements。(Anonymous inheritance)

Ex:
new ClassName ([參數列]) { 類別內容 }
new InterfaceName (){ 類別內容 }

第三,Static Nested Class 和 Inner Class的不同,說得越多越好。

Static Nested Class不能直接參考它的封裝類別(enclosing class)中的實
體變數或方法,僅能透過object instance的方式存取。
Inner Class可以直接存取它的封裝類別(enclosing class)中的變數或方法。
inner class中不能定義任何的static成員。


第四,&和&&的區別。

& 位元運算符號 && 邏輯運算符號

第五,HashMap和Hashtable的區別。

Hashtable 是thread safe class,HashMap不是。
HashMap 接受 null, 而 Hashtable 不接受。

第六,Collection 和 Collections的區別。
Collection是Interface,Collections是Class。

第七,什麼時候用assert。

測試驗證時。

第八,GC是什麼? 為什麼要有GC?

garbage collector,由JVM做記憶體管理,開發人員無須考慮這部分。

第九,String s = new String("xyz");創建了幾個String Object?

兩個… 一個是”xyz”另一個是new String(“xyz”)。

第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math.round(11.5) = 12 , Math.round(-11.5) = -11

第十一,short s1 = 1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯?

S1 +1會回傳int,int不能指定給short;
S1 += 1 沒錯。

第十二,sleep() 和 wait() 有什麼區別?

Sleep()無法由其他thread喚起,wait()可以。

第十三,Java有沒有goto?

有,屬於沒有被實作的keyword。

第十四,陣列有沒有length()這個方法? String有沒有length()這個方法?

陣列僅有length的屬性,String有。

第十五,Overload和Override的區別。Overloaded的方法是否可以改變
返回值的類型?

Overload發生在同一類別裡,Override發生在繼承關係間。
Overload為靜態連結,Override為動態連結。
可改變返回值的型態,前提是參數也要變,參數相同傳回值不同是
不被允
許的。

第十六,Set裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢?
是用==還是equals()? 它們有何區別?

用equals()。
==是比較refrence variables的內容,equals()是比較物件的內容。


第十七,給我一個你最常見到的runtime exception。
IndexOutOfBoundsException

第十八,error和exception有什麼區別?

Error 通常為不可補救的嚴重的錯誤,由 Java API或
Java virtual machine 自己丟出。

Exception 指較不嚴重的不正常狀況,他底下又定義了許多不同種類的子類別,
其中一類為 RuntimeException,表示 JVM 在執行期間發生的不正常情形。


第十九,List, Set, Map是否繼承自Collection介面?
List和Set是 ,Map不是

第二十,abstract class和interface有什麼區別?

當一個類別裡面包含有一個(含)以上的abstract method該稱類別為abstract class。
但在java中可故意宣告無abstract method的類別為abstract class。
在abstract class中可有屬性(資料成員),也可有已實作的method。

介面中全部都是abstract method並不能有constructor且僅能有
static final的屬性。


第二十一,abstract的method是否可同時是static,是否可同時是native,
是否可同時是synchronized?

不可,abstract method不可包含private, final, static, native,
synchronized
等關鍵字

第二十二,介面是否可繼承介面? 抽象類是否可實現(implements)介面?
抽象類別是否可繼承實體類別(concrete class)?

介面可繼承介面,抽象類別可implements介面,抽象類別可繼承實體類別
但前提是該實體類別要有明確的建構函數。。

第二十三,啟動一個執行緒是用run()還是start()?
start()會啟動一執行緒並呼叫其run()。

第二十四,構造器Constructor是否可被override?

No.

第二十五,是否可以繼承String類?

否,String是final Class。

第二十六,當一個執行緒進入一個物件的一個synchronized方法後,其他執行緒是否可進入此物件的其他方法?

可以。

第二十七,try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,什麼時候被執行,在return前還是後?

會在return前執行。

第二十八,程式設計題: 用最有效率的方法算出2乘以8等於幾?

2 <<3

第二十九,兩個物件值相同(x.equals(y) == true),但卻可有不同的
hash code,這句話對不對?

java.lang.Object規範equals()傳回true時,必須擁有一樣的hashcode。
實作還是可以做到不一樣的hashcode。


第三十,當一個物件被當作參數傳遞到一個方法後,此方法可改變這個物件的屬性,
並可返回變化後的結果,那麼這裏到底是值傳遞還是引用傳遞?

Call by reference.

第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?

Switch(exp),exp為整數運算式,故僅有int、 short、 char 或者 byte可以作用。

第三十二,程式設計題: 寫一個Singleton出來。

too easy...