垃圾回收機制adaptive:
- 從stack or heap 中去找reference 然後通過reference 找到所有被引用的對象,這些對象是活的,其他是dead。
- 回收第一種策略(第一階段)是 stop and copy,先系統暫停,然後把活的對象拷貝到新的一塊heap中,之後old heap 清空,效率太低,有些jvm使用的機制是把heap開在chunk中,之後直接從一個chunk複製到另一個chunk中
- 回收第二種策略(第二階段)是 mark-and-sweep,當程序運行穩定了之後,沒有或者少量垃圾產生了, 先遍歷stack or heap 把所有的life對象mark,結束之後sweep沒有標記的對象,這樣會產生碎片化的內存,如果是第一階段就採用這樣的話,效率會很低。
- JVM monitors監控內存狀態,隨時切換策略
Java 提高速度的策略in JVM - 有一種不那麼高效的策略,JIT把所有的code一次性編譯出來,然後運行,但是缺點是1) It takes a little more time, which, compounded throughout the life of the program, can add up
2) 增加了可執行文件的大小,may cause paging,會減緩程序的速度。 - lazy evaluation: JIT只編譯會被執行的code,不然就不編譯:Java HotSpot technologies,所以每一多一次運行,程序速度變快
Java初始化member various
1. 如果在函數中初始化一定要賦初值,不然報錯
2. 如果在class中初始化系統自動賦初值
3. Special initialization 可以用member method,或者member values賦值,比如我們可以這樣
//: initialization/MethodInit2.java
public class MethodInit2 {
int i = f();
int j = g(i);
int f() { return 11; }
int g(int n) { return n * 10; }
} ///:~
但是不能這樣
//: initialization/MethodInit3.java
public class MethodInit3 {
//! int j = g(i); // Illegal forward reference
int i = f();
int f() { return 11; }
int g(int n) { return n * 10; }
} ///:~
- 變量的初始化順序是按照變量在類中定義的順序進行的,而且變量初始化優先級比所有函數都高,甚至是constructor
- Static的變量初始化快於一般變量,類中先按定義的順序初始化static變量,之後按順序初始化一般變量,最後如果有靜態函數比如 static void main()再調用,而且static 初始化只發生在它必須要初始化的地方,不然就不發生,如果一個類中有static對象,但是沒有人去創建這個類,那這個static對象就不會被初始化。而且static變量不會被初始化兩次
- Constructor 默認前面加上了static修飾詞
- Static還可以這樣的使用
class Cups {
static Cup cup1;
static Cup cup2;
static {
cup1 = new Cup(1);
cup2 = new Cup(2);
}
Cups() {
print("Cups()");
}
}
- Non-static 初始化塊
//: initialization/Mugs.java
// Java "Instance Initialization."
import static net.mindview.util.Print.*;
class Mug {
Mug(int marker) {
print("Mug(" + marker + ")");
}
void f(int marker) {
print("f(" + marker + ")");
}
}
public class Mugs {
Mug mug1;
Mug mug2;
{
mug1 = new Mug(1);
mug2 = new Mug(2);
print("mug1 & mug2 initialized");
}
Mugs() {
print("Mugs()");
}
Mugs(int i) {
print("Mugs(int)");
}
public static void main(String[] args) {
print("Inside main()");
new Mugs();
print("new Mugs() completed");
new Mugs(1);
print("new Mugs(1) completed");
}
} /* Output:
Inside main()
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs()
new Mugs() completed
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs(int)
new Mugs(1) completed
*///:~
- Array initialization
Variable argument lists - Java支持不定長度不定類型的參數
Example1:不定類型不定參數個數
static void printArray(Object... args){
for(Object obj : args){
System.out.print(obj+" ");
}
System.out.println();
Example2:數組類型的args
static void printArray(Object[] args){
for(Object obj : args){
System.out.print(obj+" ");
}
System.out.println();
- 不能在同一個類裏重載Varargs,一個是有普通參數的,一個是隻有Varargs的,只能是要麼都是含有普通參數的,要麼都是隻有Varargs的
比如都有普通參數的:
public class OverloadingVarargs3 {
static void f(float i, Character... args) {
System.out.println("first");
}
static void f(char c, Character... args) {
System.out.println("second");
}
}
Enumerated 枚舉類
1. 創建
public enum Spiciness {
NOT, MILD, MEDIUM, HOT, FLAMING
}
- 枚舉類有ordinal()方法,返回它的值,有value()方法,返回一個數組記錄枚舉類的值
- 如果沒有明顯的package定義的話,那這就是默認包,只要是同一個目錄下的compilation unit(.java)都可以訪問。
- Public: interface access:這是所有人都可以訪問
- Protected:只能是該類和它的子類能訪問
Interface and implementation - 封裝(encapsulation):把數據和方法定義顯示出來但是實現隱藏了。
Class access - 如果一個java文件中你不想把這個類所有人都能訪問,那就把這個類去掉public只能package內的類能訪問。
- design pattern:Singleton意思是一個類只能被創建一個對象,這個對象只能通過特定的public方法訪問。
class Soup2 {
private Soup2() {}
// (2) Create a static object and return a reference
// upon request.(The "Singleton" pattern):
private static Soup2 ps1 = new Soup2();
public static Soup2 access() {
return ps1;
}
public void f() {}
}
}
總結
好處
1. 讓程序員知道自己需要注意什麼,而什麼東西是可以被忽略的
2. 讓這個庫的writer能夠修改private的代碼,但是又不影響程序員的代碼