<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          10分鐘搞懂各種內存溢出案例!!

          共 14122字,需瀏覽 29分鐘

           ·

          2021-05-29 21:06

          作為程序員,多多少少都會遇到一些內存溢出的場景,如果你還沒遇到,說明你工作的年限可能比較短,或者你根本就是個假程序員!哈哈,開個玩笑。今天,我們就以Java代碼的方式來列舉幾個典型的內存溢出案例,希望大家在日常工作中,盡量避免寫這些low水平的代碼。小伙伴們點贊,在看,留言,走起呀

          我們先來看看今天要介紹哪些內存溢出案例,冰河這里總結了一張圖,如下所示。

          說干就干,咱們開始吧!!

          定義主類結構

          首先,我們創(chuàng)建一個名稱為BlowUpJVM的類,之后所有的案例實驗都是基于這個類進行。如下所示。

          public class BlowUpJVM {  

          棧深度溢出

          public static void  testStackOverFlow()
                BlowUpJVM.testStackOverFlow(); 

          棧不斷遞歸,而且沒有處理,所以虛擬機棧就不斷深入不斷深入,棧深度就這樣溢出了。

          永久代內存溢出

          public static void testPergemOutOfMemory1()
             //方法一失敗 
             List<String> list = new ArrayList<String>(); 
             while(true){ 
                list.add(UUID.randomUUID().toString().intern()); 
             } 

          打算把String常量池堆滿,沒想到失敗了,JDK1.7后常量池放到了堆里,也能進行垃圾回收了。

          然后換種方式,使用cglib,用Class把老年代取堆滿

          public static void testPergemOutOfMemory2()
             try { 
                while (true) { 
                   Enhancer enhancer = new Enhancer(); 
                   enhancer.setSuperclass(OOM.class)
                   enhancer.setUseCache(false); 
                   enhancer.setCallback(new MethodInterceptor() { 
                      @Override 
                      public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable 
                         return proxy.invokeSuper(obj, args); 
                      } 
                   }); 
                   enhancer.create(); 
                } 
             } 
             catch (Exception e){ 
                e.printStackTrace(); 
             } 

          虛擬機成功內存溢出了,那JDK動態(tài)代理產(chǎn)生的類能不能溢出呢?

          public static void testPergemOutOfMemory3()
             while(true){ 
             final OOM oom = new OOM(); 
             Proxy.newProxyInstance(oom.getClass().getClassLoader(), oom.getClass().getInterfaces(), new InvocationHandler() { 
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
                      Object result = method.invoke(oom, args); 
                      return result; 
                   } 
                }); 
             } 

          事實表明,JDK動態(tài)代理差生的類不會造成內存溢出,原因是:JDK動態(tài)代理產(chǎn)生的類信息,不會放到永久代中,而是放在堆中。

          本地方法棧溢出

          public static void testNativeMethodOutOfMemory()
             int j = 0
             while(true){ 
                Printer.println(j++); 
                ExecutorService executors = Executors.newFixedThreadPool(50); 
                int i=0
                while(i++<10){ 
                   executors.submit(new Runnable() { 
                      public void run() 
                      } 
                   }); 
                } 
             } 

          這個的原理就是不斷創(chuàng)建線程池,而每個線程池都創(chuàng)建10個線程,這些線程池都是在本地方法區(qū)的,久而久之,本地方法區(qū)就溢出了。

          JVM棧內存溢出

          public static void testStackOutOfMemory()
              while (true) {   
                      Thread thread = new Thread(new Runnable() {   
                             public void run() 
                                    while(true){ 
                                } 
                             }   
                      });   
                      thread.start();   
               }   

          線程的創(chuàng)建會直接在JVM棧中創(chuàng)建,但是本例子中,沒看到內存溢出,主機先掛了,不是JVM掛了,真的是主機掛了,無論在mac還是在windows,都掛了。

          溫馨提示,這個真的會死機的。

          堆溢出

          public static void testOutOfHeapMemory()
             List<StringBuffer> list = new ArrayList<StringBuffer>(); 
             while(true){ 
                StringBuffer B = new StringBuffer(); 
                for(int i = 0 ; i < 10000 ; i++){ 
                   B.append(i); 
                } 
                list.add(B); 
             } 

          不斷往堆中塞新增的StringBuffer對象,堆滿了就直接溢出了。

          測試案例完整代碼

          public class BlowUpJVM {
              //棧深度溢出
              public static void  testStackOverFlow()
                 BlowUpJVM.testStackOverFlow(); 
           } 
              
              //不能引起永久代溢出
              public static void testPergemOutOfMemory1()
                 //方法一失敗 
                  List<String> list = new ArrayList<String>(); 
                 while(true){ 
                    list.add(UUID.randomUUID().toString().intern()); 
                 } 
              } 
              
              //永久代溢出
              public static void testPergemOutOfMemory2()
                 try { 
                    while (true) { 
                       Enhancer enhancer = new Enhancer(); 
                       enhancer.setSuperclass(OOM.class)
                       enhancer.setUseCache(false); 
                       enhancer.setCallback(new MethodInterceptor() { 
                          @Override 
                          public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable 
                             return proxy.invokeSuper(obj, args); 
                          } 
                       }); 
                       enhancer.create(); 
                    } 
                 } 
                 catch (Exception e){ 
                    e.printStackTrace(); 
                 } 
              } 
              
              //不會引起永久代溢出
              public static void testPergemOutOfMemory3()
                 while(true){ 
                 final OOM oom = new OOM(); 
                 Proxy.newProxyInstance(oom.getClass().getClassLoader(), oom.getClass().getInterfaces(), new InvocationHandler() { 
                       public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
                          Object result = method.invoke(oom, args); 
                          return result; 
                       } 
                    }); 
                 } 
              } 
              
              //本地方法棧溢出
              public static void testNativeMethodOutOfMemory()
                 int j = 0
                 while(true){ 
                    Printer.println(j++); 
                    ExecutorService executors = Executors.newFixedThreadPool(50); 
                    int i=0
                    while(i++<10){ 
                       executors.submit(new Runnable() { 
                          public void run() 
                          } 
                       }); 
                    } 
                 } 
              } 
              
              //JVM內存溢出
              public static void testStackOutOfMemory()
                  while (true) {   
                          Thread thread = new Thread(new Runnable() {   
                                 public void run() 
                                        while(true){ 
                                    } 
                                 }   
                          });   
                          thread.start();   
                   }   
              } 
              
              //堆溢出
              public static void testOutOfHeapMemory()
                 List<StringBuffer> list = new ArrayList<StringBuffer>(); 
                 while(true){ 
                    StringBuffer B = new StringBuffer(); 
                    for(int i = 0 ; i < 10000 ; i++){ 
                       B.append(i); 
                    } 
                    list.add(B); 
                 } 
              } 

          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  男女啪啪网站国产 | 国产av深夜福利 国产AV综合播放 国产ol在线观看 | 草操网| 天天日天天做 | 综合色色综合 |