<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    于吉吉的技術博客

    建造高性能門戶網

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      65 隨筆 :: 6 文章 :: 149 評論 :: 0 Trackbacks

    上段時間有臺機器發生了 java.lang.OutOfMemoryError: PermGen space 內存溢出的異常,當時大概判斷了原因后就把 MaxPermSize 配置調高后,就把問題解決了,不過空下時間后還是需要繼續把review代碼。

    一般來說PermSize Space OOM的話,第一種可能就是方法區溢出,第二種就是運行時常量池溢出,第二種查看后基本排除掉,問題就應該出現在方法區的溢出,方法區用于存放class的相關信息,如類名,訪問修飾符,常量池,字段描述,方法描述等等,對于這個區域的溢出,基本上都是運行時產生大量的類填滿了整個方法區,直到溢出。

    spring aop中都是使用到了cglib這類字節碼的技術,動態代理的類越多,就需要越多的方法區來保證動態生成的class可以加載入到內存中去,
    不過spring框架導致的不會因為這種原因。撐爆perm的應該是各種methodaccessorX和constructoracccessorX等等。本來這些accessor也有緩存,但它們使用內存大小敏感的reference引用著的,且使用的是堆內存。當你堆內存吃緊的時候,這些緩存就摧毀了,就必然會不斷產生新的methodAccessor字節碼,是這個撐爆了perm。所以除增大permsize還應該看看平時運行時堆內存是不是經常用光

    下面的例使用cglib直接進行動態代理產生大量的動態類,然后使用jconsole進行觀察。

    首先將本機的jvm配置為 -XX:PermSize=64M -XX:MaxPermSize=64M ,給到PermSize最大為64M的內存

    public class PermgenOOM {

        
    public static void main(String[] args) throws InterruptedException {
            
    int i=0;
            
    while(true){
                Enhancer enhancer 
    = new Enhancer();
                enhancer.setSuperclass(Product.
    class);
                enhancer.setUseCache(
    false);// 關閉CGLib緩存,否則總是生成同一個類
                enhancer.setCallback(new MethodInterceptor() {                
                    @Override
                    
    public Object intercept(Object obj, Method method, Object[] args,
                            MethodProxy methodproxy) 
    throws Throwable {
                        
    // TODO Auto-generated method stub
                        return methodproxy.invokeSuper(obj,args);
                    }
                });
                enhancer.create();
                Thread.sleep(
    100);
            }
        }
    }

    很快,系統就拋出了 java.lang.OutOfMemoryError: PermGen space
    內存池peimgen的情況


    加載類的情況



    并且在方法區中,一個類如果要被垃圾收集器回收掉,判斷的條件是非??量痰?,很多人都把方法區稱為“永久區”(Permanent Generation),但據說2者在本質上是不一致的,另外還有稱呼為“非堆區”,不糾結這個了。

    再看看enhancer.setUseCache(false),如果選擇為true的話,那么就使用和更新一類具有相同屬性生成的類的靜態緩存,而不會在同一個類文件還繼續被動態加載并視為不同的類,這個其實跟類的equals()和hashCode()有關,它們是與cglib內部的class cache的key相關的。

    將上面的程序 enhancer.setUseCache(false) 改為 enhancer.setUseCache(ture)

    public class PermgenOOM {

        
    public static void main(String[] args) throws InterruptedException {
            
    int i=0;
            
    while(true){
                Enhancer enhancer 
    = new Enhancer();
                enhancer.setSuperclass(Product.
    class);
                enhancer.setUseCache(
    true);// 或者不寫,默認值就是true
                enhancer.setCallback(new MethodInterceptor() {                
                    @Override
                    
    public Object intercept(Object obj, Method method, Object[] args,
                            MethodProxy methodproxy) 
    throws Throwable {
                        
    // TODO Auto-generated method stub
                        return methodproxy.invokeSuper(obj,args);
                    }
                });
                enhancer.create();
                Thread.sleep(
    100);
            }
        }
    }

    內存池peimgen的情況


    加載類的情況



    可以發現內存池peimgen和加載類的情況并沒有呈現直線上漲,已經他們一直都使用者動態類生成類的靜態緩存,但是這種動態創建類使用靜態緩存在一些情況下并不適合需求。


    posted on 2011-08-21 15:55 陳于喆 閱讀(6426) 評論(0)  編輯  收藏 所屬分類: web開發java
    主站蜘蛛池模板: 成人A级毛片免费观看AV网站| 美女内射无套日韩免费播放| 在线不卡免费视频| 国产免费播放一区二区| 国产高清免费在线| 久久亚洲色WWW成人欧美| 日韩电影免费在线观看视频| 亚洲国产精品无码久久久秋霞1| 免费无码AV电影在线观看| 亚洲www在线观看| 成全视频免费高清 | 亚洲熟妇AV日韩熟妇在线| 国产精品久久久久久久久久免费| 亚洲熟妇AV一区二区三区宅男| 永久免费看bbb| 尤物视频在线免费观看| 国产专区一va亚洲v天堂| 免费在线看黄的网站| 久久久久亚洲av无码专区导航| xxxxx免费视频| 国产成人亚洲综合无| 亚洲中文字幕成人在线| 人人揉揉香蕉大免费不卡| 亚洲欧洲精品国产区| 日本高清免费不卡在线| 国产成人高清精品免费观看| 亚洲AV成人无码久久精品老人| 无码人妻精品中文字幕免费东京热| 亚洲一区精彩视频| 国产91精品一区二区麻豆亚洲 | 亚洲国产精品久久| 免费观看AV片在线播放| 精品在线免费视频| 亚洲精品无码mv在线观看网站| 99久久精品日本一区二区免费| 亚洲国产精华液2020| 亚洲午夜久久久久久噜噜噜| 久久午夜夜伦鲁鲁片免费无码影视| 亚洲国产av玩弄放荡人妇| 国产偷国产偷亚洲高清日韩| 久久成人国产精品免费软件|