本文改編自[我是一個 Java class](hhttps://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=416976590&idx=1&sn=22823ada76d8cfd26a43e8d3a7b7a60e&scene=21#wechat_redirect)
## Classloader
javac把java代碼變成了class文件,可以通過的文件開頭的幾個數來確定的是否是java的類以及是由jdk的哪個版本編譯出來的
那么如何找到class文件呢?
* 在環境變量里面設置的路徑找
* 如果使用Eclipse編譯,可能會多三級,比如com/mytaobao/domain
* 如果找不到,會拋出ClassNotFound異常。
假設這個class文件的全名叫 com.mytaobao.domain.Account
## classLoader的分級
為什么的classLoader分級呢?
因為之前有個黑客類寫了java.lang.String,與String的名字一模一樣,但是里面竟然有格式化硬盤的代碼。
為了預防這種風險,可以將ClassLoader分層,像String,ArrayList等只能由最頂層的Bootstrap,Extension等Classloader來加載,如果加載不了,再問AppClassloader
而文件驗證器的主要作用是對class中的字節碼進行檢查分析,確保每個指令是正確的,檢查是不是有超類,是不是覆蓋了final方法,跳轉指令是否正確。
## 虛擬機
class會被加載到內存中的方法區,然后new一個新的Account對象,編號是"Account@659e0bfd"
這個對象會被放到堆里面。
當CPU開始調用某個線程的時候,會開始調用class,因為線程會按照class的機器碼進行執行


使用棧的原因在于簡單。
只需要入棧和出棧就行了,不像intel的CPU中的桶,每個桶只能容納一個數(寄存器),做加法的時候,需要把數放到不同的桶里面,然后加起來的結果還得放到新桶里面。
線程有不止一個工作臺, 而是一摞子工作臺, 也是一個壓一個, 線程們都很老實,永遠在最上面那個工作, 從來不會先干下面的活。
這些工作臺也是棧,學名叫 Java 棧,每個線程都有一個, 其中的每個工作臺你看過了 ,學名叫棧幀, 每個臺子都代表一個方法調用, 這一摞工作臺就方法調用方法導致的啊
一旦調用新方法, 立刻就會形成一個新的工作臺, 壓在老的上面。 方法調用完成后, 棧頂的工作臺就被銷毀了, 線程會在底下的工作臺繼續機械的干活。
## 堆
清理者:專門清理沒有用的對象,比如說Account@659e0bfd,他可能是一個局部變量,方法結束后就沒人引用了,如果不清理就會住滿,out of memory
那么可以多分配些空間給堆嗎?這是由程序員決定的,在啟動虛擬機的時候會指定參數。
那么清理者如何知道對象是否有人用?可以看引用計數。
如果對象被使用, 計數就會增加, 不用的時候就會減少, 如果是 0 , 那就可能被清理。