熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

內存溢出場景模擬

2013-11-23 19:09:49  來源: Java核心技術 

   Java Method Stack 棧溢出實驗什麼時候會讓 Java Method Stack 棧溢出啊?棧的基本特點就是 FILO(First In Last Out)如果 in 的太多而 out 的太少就好 overflow 了而 Java Method Stack 的功能就是保存每一次函數調用時的現場即為入棧函數返回就對應著出棧所以函數調用的深度越大棧就變得越大足夠大的時候就會溢出所以模擬 Java Method Stack 溢出只要不斷遞歸調用某一函數就可以

  程序源碼

  // Author  Poechant // Blog    /poechant // Email   zhognchaoustc# (#>@)

  // Args    verbosegc XssK

  package comsinosupermanmain

  public class Test {

  private int stackLength =

  public void stackOverflow() { ++stackLengthstackOverflow()}

  public static void main(String[] args) throws Throwable { Test test = new Test()

  try { teststackOverflow()} catch (Throwable e) { Systemoutprintln(stack length + teststackLength)throw e}運行結果

  stack length Exception in thread main javalangStackOverflowError at comsinosupermanmainTeststackOverflow(Testjava

  at comsinosupermanmainTeststackOverflow(Testjava

  ……

   Java Method Stack 內存溢出實驗Heap 內存溢出

  堆是用來存儲對象的當然對象不一定都存在堆裡(由於逃逸技術的發展)那麼堆如果溢出了一定是不能被殺掉的對象太多了模擬 Heap 內存溢出只要不斷創建對象並保持有引用存在即可

  程序源碼

  // Author  Poechant // Blog    /poechant // Email   zhongchaoustc# (#>@)

  // Args    verbosegc Xmxm Xmsm

  package comsinosupermanmain

  import javautilArrayListimport javautilList

  public class Test {

  private static class HeapOomObject { }

  public static void main(String[] args) { List<HeapOomObject> list = new ArrayList<HeapOomObject>()while (true) { listadd(new HeapOomObject())}運行結果

  [GC K>K(K) secs] [GC K>K(K) secs] [GC K(K) secs] [Full GC K>K(K) secs] [Full GC K>K(K) secs] [GC K(K) secs] [Full GC K>K(K) secs] [Full GC K>K(K) secs] [Full GC K>K(K) secs] [GC K(K) secs] [Full GC K>K(K) secs] [Full GC K>K(K) secs] [Full GC K>K(K) secs] Exception in thread main javalangOutOfMemoryError Java heap space at comsinosupermanmainTestmain(Testjava

   Method Area 內存溢出也就是 Nonheap是用來存儲 Object Class Data常量靜態變量JIT 編譯後的代碼等如果該區域溢出則說明某種數據創建的實在是太多了模擬的話可以不斷創建新的 class直到溢出為止

  以下代碼使用到 cglibjar 和 asmalljar

  程序源碼

  package comsinosupermanmain

  import javalangreflectMethod

  import netsfcglibproxyEnhancerimport netsfcglibproxyMethodInterceptorimport netsfcglibproxyMethodProxy

  public class Test { static class MethodAreaOomObject { } public static void main(String[] args) { while(true){ Enhancer enhancer = new Enhancer()enhancersetSuperclass(MethodAreaOomObjectclass)enhancersetUseCache(false)enhancersetCallback(new MethodInterceptor() { public Object intercept(Object obj Method method Object[] argsMethodProxy proxy) throws Throwable { return proxyinvoke(obj args)} })enhancercreate()}運行結果

  Exception in thread main reCodeGenerationException   javalangreflectInvocationTargetException——>null at reAbstractClassGeneratorcreate(AbstractClassGeneratorjava

  at netsfcglibproxyEnhancercreateHelper(Enhancerjava

  at netsfcglibproxyEnhancercreate(Enhancerjava

  at comsinosupermanmainTestmain(Testjava

  Caused by javalangreflectInvocationTargetException at sunreflectGeneratedMethodAccessorinvoke(Unknown Source)

  at sunreflectDelegatingMethodAccessorImplinvoke(DelegatingMethodAccessorImpljava

  at javalangreflectMethodinvoke(Methodjava

  at reReflectUtilsdefineClass(ReflectUtilsjava

  at reAbstractClassGeneratorcreate(AbstractClassGeneratorjava

  …… more Caused by javalangOutOfMemoryError PermGen space at javalangClassLoaderdefineClass(Native Method)

  at javalangClassLoaderdefineClassCond(ClassLoaderjava

  at javalangClassLoaderdefineClass(ClassLoaderjava

  …… more Runtime Constant Pool in Method Area 內存溢出在運行時產生大量常量就可以實現讓 Method Area 溢出的目的運行是常量可以用 String 類的 intern 方法不斷地產生新的常量

  程序源碼

  package comsinosupermanmain

  import javautilArrayListimport javautilList

  public class Test { public static void main(String[] args) { List<String> list = new ArrayList<String>()int i = while (true) { listadd(StringvalueOf(i++)intern())}運行結果

  Exception in thread main javalangOutOfMemoryError PermGen space at javalangStringintern(Native Method)

  at comsinosupermanmainTestmain(Testjava

  結語在實際編碼中要盡量避免此類錯誤不過大多數程序設計的結構比這裡的示例要復雜的多使得問題被隱藏但 JVM 的內存溢出問題本質上大都可歸結為以上這幾種情況


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26375.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.