JVM相关问题
問:堆和棧有什么區別
答:堆是存放對象的,但是對象內的臨時變量是存在棧內存中,如例子中的methodVar是在運行期存放到棧中的。
棧是跟隨線程的,有線程就有棧,堆是跟隨JVM的,有JVM就有堆內存。
?
問:堆內存中到底存在著什么東西?
答:對象,包括對象變量以及對象方法。
?
問:類變量和實例變量有什么區別?
答:靜態變量是類變量,非靜態變量是實例變量,直白的說,有static修飾的變量是靜態變量,沒有static修飾的變量是實例變量。靜態變量存在方法區中,實例變量存在堆內存中。
?
問:我聽說類變量是在JVM啟動時就初始化好的,和你這說的不同呀!
答:那你是道聽途說,信我的,沒錯。
?
問:Java的方法(函數)到底是傳值還是傳址?
答:都不是,是以傳值的方式傳遞地址,具體的說原生數據類型傳遞的值,引用類型傳遞的地址。對于原始數據類型,JVM的處理方法是從Method Area或Heap中拷貝到Stack,然后運行frame中的方法,運行完畢后再把變量指拷貝回去。
?
問:為什么會產生OutOfMemory產生?
答:一句話:Heap內存中沒有足夠的可用內存了。這句話要好好理解,不是說Heap沒有內存了,是說新申請內存的對象大于Heap空閑內存,比如現在Heap還空閑1M,但是新申請的內存需要1.1M,于是就會報OutOfMemory了,可能以后的對象申請的內存都只要0.9M,于是就只出現一次OutOfMemory,GC也正常了,看起來像偶發事件,就是這么回事。???????但如果此時GC沒有回收就會產生掛起情況,系統不響應了。
?
問:我產生的對象不多呀,為什么還會產生OutOfMemory?
答:你繼承層次忒多了,Heap中?產生的對象是先產生?父類,然后才產生子類,明白不?
?
問:OutOfMemory錯誤分幾種?
答:分兩種,分別是“OutOfMemoryError:java heap size”和”OutOfMemoryError: PermGen space”,兩種都是內存溢出,heap size是說申請不到新的內存了,這個很常見,檢查應用或調整堆內存大小。
“PermGen space”是因為永久存儲區滿了,這個也很常見,一般在熱發布的環境中出現,是因為每次發布應用系統都不重啟,久而久之永久存儲區中的死對象太多導致新對象無法申請內存,一般重新啟動一下即可。
?
問:為什么會產生StackOverflowError?
答:因為一個線程把Stack內存全部耗盡了,一般是遞歸函數造成的。
?
問:一個機器上可以看多個JVM嗎?JVM之間可以互訪嗎?
答:可以多個JVM,只要機器承受得了。JVM之間是不可以互訪,你不能在A-JVM中訪問B-JVM的Heap內存,這是不可能的。在以前老版本的JVM中,會出現A-JVM Crack后影響到B-JVM,現在版本非常少見。
?
問:為什么Java要采用垃圾回收機制,而不采用C/C++的顯式內存管理?
答:為了簡單,內存管理不是每個程序員都能折騰好的。
?
問:為什么你沒有詳細介紹垃圾回收機制?
答:垃圾回收機制每個JVM都不同,JVM Specification只是定義了要自動釋放內存,也就是說它只定義了垃圾回收的抽象方法,具體怎么實現各個廠商都不同,算法各異,這東西實在沒必要深入。
?
問:JVM中到底哪些區域是共享的?哪些是私有的?
答:Heap和Method Area是共享的,其他都是私有的,
?
問:什么是JIT,你怎么沒說?
答:JIT是指Just In Time,有的文檔把JIT作為JVM的一個部件來介紹,有的是作為執行引擎的一部分來介紹,這都能理解。Java剛誕生的時候是一個解釋性語言,別噓,即使編譯成了字節碼(byte code)也是針對JVM的,它需要再次翻譯成原生代碼(native code)才能被機器執行,于是效率的擔憂就提出來了。Sun為了解決該問題提出了一套新的機制,好,你想編譯成原生代碼,沒問題,我在JVM上提供一個工具,把字節碼編譯成原生碼,下次你來訪問的時候直接訪問原生碼就成了,于是JIT就誕生了,就這么回事。
?
問:JVM還有哪些部分是你沒有提到的?
答:JVM是一個異常復雜的東西,寫一本磚頭書都不為過,還有幾個要說明的:
常量池(constant pool):按照順序存放程序中的常量,并且進行索引編號的區域。比如int i =100,這個100就放在常量池中。
安全管理器(Security Manager):提供Java運行期的安全控制,防止惡意攻擊,比如指定讀取文件,寫入文件權限,網絡訪問,創建進程等等,Class Loader在Security Manager認證通過后才能加載class文件的。
方法索引表(Methods table),記錄的是每個method的地址信息,Stack和Heap中的地址指針其實是指向Methodstable地址。
??????
問:為什么不建議在程序中顯式的生命System.gc()?
答:因為顯式聲明是做堆內存全掃描,也就是Full GC,是需要停止所有的活動的(Stop??TheWorld Collection),你的應用能承受這個嗎?
?
問:JVM有哪些調整參數?
答:非常多,自己去找,堆內存、棧內存的大小都可以定義,甚至是堆內存的三個部分、新生代的各個比例都能調整。
問:jvm 運行時的數據區和哪些是線程公用的:
答:圖中五大區域就是運行時的內存區,其中棧被分為虛擬機棧和本地方法棧,虛擬機棧是java自己碼方法對應的棧,而本地方法是c代碼方法對應的棧。
其中綠色圈起來的是不可以公用的,是線程獨自創建和占用的,這個涉及具體的線程執行。
來自jameswxx 樵夫后院的博客
總結
- 上一篇: DNF100级天帝怎么加点 100级天帝
- 下一篇: 【Java面试题】MySQL索引底层为什