JDK1.7和1.8 JAVA內(nèi)存的使用方式有些不同,本文將為您詳細(xì)介紹。
JDK1.7中的內(nèi)存分為永久區(qū)、堆區(qū)、棧區(qū)和方法區(qū)。其中,永久區(qū)主要存儲(chǔ)一些類信息、方法信息和常量等。堆區(qū)主要是存儲(chǔ)對(duì)象實(shí)例和數(shù)組等數(shù)據(jù)結(jié)構(gòu)。棧區(qū)主要是存儲(chǔ)線程運(yùn)行時(shí)的狀態(tài)信息和方法調(diào)用棧等。方法區(qū)則主要是存儲(chǔ)類的類型信息、常量池等數(shù)據(jù)。但在JDK1.7中,永久區(qū)的內(nèi)存容易出現(xiàn)OOM(OutOfMemory)的問(wèn)題,導(dǎo)致程序拋出異常。
public static void main(String[] args) { List<String> list = new ArrayList<>(); for (int i = 0; i < 1000000000; i++) { list.add(String.valueOf(i).intern()); } }
上面的代碼就可以讓程序在JDK1.7中出現(xiàn)OOM的問(wèn)題,因?yàn)镾tring.valueOf(i).intern()方法會(huì)將字符串常量放入永久區(qū)中,而永久區(qū)的大小是有限制的。
相比之下,JDK1.8中拋棄了永久區(qū)的概念,取而代之的是Metaspace(元空間)。Metaspace是堆區(qū)的一部分,用于存儲(chǔ)類的類型信息和常量池等數(shù)據(jù)。由于Metaspace的大小是動(dòng)態(tài)可調(diào)整的,因此可以有效避免JDK1.7中出現(xiàn)的OOM問(wèn)題。
public static void main(String[] args) { List<String> list = new ArrayList<>(); for (int i = 0; i < 1000000000; i++) { list.add(String.valueOf(i).intern()); } }
相同的代碼在JDK1.8中不會(huì)出現(xiàn)OOM的問(wèn)題,因?yàn)樽址A坎辉俜湃胗谰脜^(qū),而是存儲(chǔ)在堆區(qū)的Metaspace中。
綜上所述,JDK1.8相比JDK1.7在內(nèi)存管理上有了更多的優(yōu)化,使得程序出現(xiàn)OOM問(wèn)題的概率更小,對(duì)于大規(guī)模的Java應(yīng)用來(lái)說(shuō)是個(gè)好消息。