標籤:java 虛擬機器 jvm thiking in java
最近開始讀tij,好急性不如爛筆頭,所以還是記錄一下,方便以後查閱。
一、各種初始化問題:
方法重載的問題:
方法的重載,區別是靠傳入方法的參數,而不是返回值。比如f(),如果是返回值的話,容易產生歧義。
方法的重載中,會出現傳入參數的型別提升或者降低;比如說如果有個方法可以接受int型,如果傳入一個char類型,調用該方法的話會被自動提升。
如果涉及到可變參數方法的重載問題,那麼會出現一些特殊情況:
static void f(float f, Character... c) {System.out.println("first");}static void f(Character... c) {// 如果這裡不在前面加一個char c1,則會引起編譯錯誤System.out.println("second");}
f("1","2");//這時會出現編譯錯誤
要將第二個方法寫成下面這種方式:
static void f(char c1, Character... c) {// 如果這裡不在前面加一個char c1,則會引起編譯錯誤System.out.println("second");}
static相關的初始化問題:
1、對於一個類而言,靜態成員變數或者靜態塊的初始化,會在main方法之前之前執行,如果main方法在該類裡面的話。
2、靜態成員變數,或者靜態塊之間的初始化順序,由它們之間出現的順序的早晚來確定。
3、static塊只會被執行一次,就是在類被載入的時候,所以對於一個類而言,如果通過new來調用其構造方法來建立一個對象,如果是第一次,那麼static塊會在這之前被執行,之後再進行new,則不會再次執行。
package com.alex.example;class Cup {Cup(int maker) {System.out.println("Cup(" + maker + ")");}void f(int maker) {System.out.println("f(" + maker + ")");}}class Cups {static Cup cup1;static Cup cup2 = new Cup(2);static {System.out.println("static block in Cups is running");cup1 = new Cup(1);// cup2 = new Cup(2);}Cups() {System.out.println("Cups()");}}public class ExplicitStatic {public static void main(String[] args) {System.out.println("Inside main");Cups.cup1.f(99);}static Cups cups1 = new Cups();// static Cups cups2 = new Cups();}
二、記憶體回收的問題:
Java的記憶體回收,可以簡單的概括為:自適應的,分代的,停止-複製,標記-清掃 式的記憶體回收。
停止-複製
就是將所有線程都停止,stop the world,然後將不要回收的資料,複製到一塊沒有使用的記憶體中,然後將剩下的記憶體內容都清理掉。比較費時。
標記-清掃
標記-清掃也需要將線程停止,然後將要回收的資料標記出來,然後回收掉,這樣一般速度會比上面的快,但是卻會產生記憶體片段。
自適應
自適應的意思是,Java虛擬機器,會自適應的,在垃圾比較多的時候,採用停止複製,而在垃圾比較少,進入穩週期性時候,採用標記清理。
分代
分代意思是,將記憶體中的資料區塊進行標定,如果一個資料區塊,每熬過一次記憶體回收,那麼就給它的代數加1,熬過數次的資料,就可能進行老年代的記憶體中,而對於一些比較大的資料,可能它產生出來就會直接進入老年代,而不會在新生代,所以我們最好不要頻繁的建立一些生命週期短的,體積龐大的資料,這可能會導致JVM頻繁地進行完全記憶體回收。
【thinking in java】讀書筆記(一)