<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 相關特征 ### 方法區特征 * 同 Java 堆一樣,方法區也是全局共享的一塊內存區域 * 方法區的作用是存儲 Java 類的結構信息,當我們創建對象實例后,對象的類型信息存儲在方法區之中,實例數據存放在堆中;實例數據指的是在 Java 中創建的各種實例對象以及它們的值,類型信息指的是定義在 Java 代碼中的常量、靜態變量、以及在類中聲明的各種方法、方法字段等等;同事可能包括即時編譯器編譯后產生的代碼數據。 * JVMS 不要求該區域實現自動的內存管理,但是商用 JVM 一般都已實現該區域的自動內存管理。 * 方法區分配內存可以不連續,可以動態擴展。 * 該區域并非像 JMM 規范描述的那樣數據一旦放進去就屬于 “永久代”;在該區域進行內存回收的主要目的是對常量池的回收和對內存數據的卸載;一般來說這個區域的內存回收效率比起 Java 堆要低得多。 * 當方法區無法滿足內存需求時,將拋出 OutOfMemoryError 異常。 ### 運行時常量池的特征 * 運行時常量池是方法區的一部分,所以也是全局共享的。 * 其作用是存儲 Java 類文件常量池中的符號信息。 * class 文件中存在常量池(非運行時常量池),其在編譯階段就已經確定;JVM 規范對 class 文件結構有著嚴格的規范,必須符合此規范的 class 文件才會被 JVM 認可和裝載。 * 運行時常量池 中保存著一些 class 文件中描述的符號引用,同時還會將這些符號引用所翻譯出來的直接引用存儲在 運行時常量池 中。 * 運行時常量池相對于 class 常量池一大特征就是其具有動態性,Java 規范并不要求常量只能在運行時才產生,也就是說運行時常量池中的內容并不全部來自 class 常量池,class 常量池并非運行時常量池的唯一數據輸入口;在運行時可以通過代碼生成常量并將其放入運行時常量池中。 * 同方法區一樣,當運行時常量池無法申請到新的內存時,將拋出 OutOfMemoryError 異常。 ## HotSpot 方法區變遷 ### JDK1.2 ~ JDK6 在 JDK1.2 ~ JDK6 的實現中,HotSpot 使用永久代實現方法區;HotSpot 使用 GC 分代實現方法區帶來了很大便利; ### JDK7 由于 GC 分代技術的影響,使之許多優秀的內存調試工具無法在 Oracle HotSpot之上運行,必須單獨處理;并且 Oracle 同時收購了 BEA 和 Sun 公司,同時擁有 JRockit 和 HotSpot,在將 JRockit 許多優秀特性移植到 HotSpot 時由于 GC 分代技術遇到了種種困難,所以從 JDK7 開始 Oracle HotSpot 開始移除永久代。 JDK7中符號表被移動到 Native Heap中,字符串常量和類引用被移動到 Java Heap中。 ### JDK8 在 JDK8 中,永久代已完全被元空間(Meatspace)所取代。 ## 永久代變遷產生的影響 ### 測試代碼1 ``` public class Test1 { public static void main(String[] args) { String s1 = new StringBuilder("漠").append("然").toString(); System.out.println(s1.intern() == s1); String s2 = new StringBuilder("漠").append("然").toString(); System.out.println(s2.intern() == s2); } } ``` 以上代碼,在 JDK6 下執行結果為 false、false,在 JDK7 以上執行結果為 true、false。 首先明確兩點: 1、在 Java 中直接使用雙引號展示的字符串將會在常量池中直接創建。 2、String 的 intern 方法首先將嘗試在常量池中查找該對象,如果找到則直接返回該對象在常量池中的地址;找不到則將該對象放入常量池后再返回其地址。JDK6 常量池在方法區,頻繁調用該方法可能造成 OutOfMemoryError。 產生兩種結果的原因: 在 JDK6 下 s1、s2 指向的是新創建的對象,該對象將在 Java Heap 中創建,所以 s1、s2 指向的是 Java Heap 中的內存地址;調用 intern 方法后將嘗試在常量池中查找該對象,沒找到后將其放入常量池并返回,所以此時 s1/s2.intern() 指向的是常量池中的地址,JDK6常量池在方法區,與堆隔離,;所以 s1.intern()==s1 返回false。 ### 測試代碼2 ``` public class Test2 { public static void main(String[] args) { /** * 首先設置 持久代最大和最小內存占用(限定為10M) * VM args: -XX:PermSize=10M -XX:MaxPremSize=10M */ List<String> list = new ArrayList<String>(); // 無限循環 使用 list 對其引用保證 不被GC intern 方法保證其加入到常量池中 int i = 0; while (true) { // 此處永久執行,最多就是將整個 int 范圍轉化成字符串并放入常量池 list.add(String.valueOf(i++).intern()); } } } ``` 以上代碼在 JDK6 下會出現 Perm 內存溢出,JDK7 or high 則沒問題。 原因分析: JDK6 常量池存在方法區,設置了持久代大小后,不斷while循環必將撐滿 Perm 導致內存溢出;JDK7 常量池被移動到 Native Heap(Java Heap),所以即使設置了持久代大小,也不會對常量池產生影響;不斷while循環在當前的代碼中,所有int的字符串相加還不至于撐滿 Heap 區,所以不會出現異常。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看