下面這個圖,很清楚地說明對象在new的時候是怎樣開辟內存空間的

其中對象new出來的,是棧內存,變量的開辟是堆內存


Java的一個重要優點就是通過垃圾收集器GC (Garbage Collection)自動管理內存的回收,程序員不需要通過調用函數來釋放內存。因此,很多程序員認為Java 不存在內存泄漏問題,或者認為即使有內存泄漏也不是程序的責任,而是GC 或JVM的問題。其實,這種想法是不正確的,因為Java 也存在內存泄漏,但它的表現與C++不同。如果正在開發的Java 代碼要全天24 小時在服務器上運行,則內存漏洞在此處的影響就比在配置實用程序中的影響要大得多,即使最小的漏洞也會導致JVM耗盡全部可用內存。另外,在很多嵌入式系統中,內存的總量非常有限。在相反的情況下,即便程序的生存期較短,如果存在分配大量臨時對象(或者若干吞噬大量內存的對象)的任何Java 代碼,而且當不再需要這些對象時也沒有取消對它們的引用,則仍然可能達到內存極限。
Java 的內存管理就是對象的分配和釋放問題。分配內存的方式多種多樣,取決於該種語言的語法結構。但不論是哪一種語言的內存分配方式,最后都要返回所分配的內存塊的起始地址,即返回一個指針到內存塊的首地址。在Java 中所有對象都是在堆(Heap)中分配的,對象的創建通常都是采用new或者是反射的方式,但對象釋放卻有直接的手段,所以對象的回收都是由Java虛擬機通過垃圾收集器去完成的。這種收支兩條線的方法確實簡化了程序員的工作,但同時也加重了JVM的工作,這也是Java 程序運行速度較慢的原因之一。因為,GC 為了能夠正確釋放對象,GC 必須監控每一個對象的運行狀態,包括對象的申請、引用、被引用、賦值等,GC 都需要進行監控。監視對象狀態是為了更加准確地、及時地釋放對象,而釋放對象的根本原則就是該對象不再被引用。
Java 使用有向圖的方式進行內存管理,可以消除引用循環的問題,例如有三個對象,相互引用,只要它們和根進程不可達,那么GC 也是可以回收它們的。在Java 語言中,判斷一塊內存空間是否符合垃圾收集器收集標准的標准只有兩個:一個是給對象賦予了空值null,以下再沒有調用過,另一個是給對象賦予了新值,即 重新分配了內存空間。
