垃圾回收机制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的代码,但是又不影响程序员的代码