posts - 15,comments - 65,trackbacks - 0
                想必不少人聽說過javaagent,但是很少人聽說Instrumentation,其實Instrumentation就是javaagent的實現(xiàn)機(jī)制,說到Instrumentation,就必須想了解javaattach機(jī)制,那就先說下attach的實現(xiàn)。

                  大家進(jìn)行jstack的時候,是不是經(jīng)常看到兩個線程Signal Dispatcher Attach Listener線程,可能不知道是干嘛的吧,這兩個線程是實現(xiàn)attach的關(guān)鍵所在,其中前者是在jvm啟動的時候就會創(chuàng)建的,后者只有接收過attach請求的時候vm才會創(chuàng)建,顧名思義,Signal Dispatcher是分發(fā)信號的, Attach Listener 是處理attach請求的,那么兩者有什么關(guān)系呢,當(dāng)我們執(zhí)行attach方法的時候,會向目標(biāo)vm發(fā)出一個SIGQUIT 的信號,目標(biāo)vm收到這個信號之后就會創(chuàng)建Attach Listener線程了,當(dāng)然jvm保證了不會多創(chuàng)建。
           1  path = findSocketFile(pid);
           2         if (path == null) {
           3             File f = new File(tmpdir, ".attach_pid" + pid);
           4             createAttachFile(f.getPath());
           5             try {
           6                 sendQuitTo(pid);
           7 
           8                 // give the target VM time to start the attach mechanism
           9                 int i = 0;
          10                 long delay = 200;
          11                 int retries = (int)(attachTimeout() / delay);
          12                 do {
          13                     try {
          14                         Thread.sleep(delay);
          15                     } catch (InterruptedException x) { }
          16                     path = findSocketFile(pid);
          17                     i++;
          18                 } while (i <= retries && path == null);
          19                 if (path == null) {
          20                     throw new AttachNotSupportedException(
          21                         "Unable to open socket file: target process not responding " +
          22                         "or HotSpot VM not loaded");
          23                 }
          24             } finally {
          25                 f.delete();
          26             }
          27         }
                  Attach機(jī)制說得簡單點就是提供A進(jìn)程可以連上B進(jìn)程(當(dāng)然是java進(jìn)程),創(chuàng)建socket進(jìn)行通信,A通過發(fā)命令給B,B然后對命令進(jìn)行截取從自己的vm中獲取信息發(fā)回給客戶端vm,但是并不是隨便發(fā)指令都會處理的,那么attach Listener接收哪些命令呢,如下所示
          static AttachOperationFunctionInfo funcs[] = {
            { "agentProperties",  get_agent_properties },
            { "datadump",         data_dump },
            { "dumpheap",         dump_heap },
            { "load",             JvmtiExport::load_agent_library },
            { "properties",       get_system_properties },
            { "threaddump",       thread_dump },
            { "inspectheap",      heap_inspection },
            { "setflag",          set_flag },
            { "printflag",        print_flag },
            { "jcmd",             jcmd },
            { NULL,               NULL }
          };
                   Instrumentation的實現(xiàn)其實主要使用了load這個指令,它用來實現(xiàn)讓target vm動態(tài)加載agentlib,Instrumentation的實現(xiàn)在一個名為libinstrument.dylib的動態(tài)lib庫,linux下是libinstrument.so,它是基于jvmti接口實現(xiàn)的,因此在對其進(jìn)行l(wèi)oad的時候會創(chuàng)建一個agent實例,并往jvmti環(huán)境注冊一些回調(diào)方法,比如監(jiān)聽類文件加載的事件,vm初始化完成事件等,執(zhí)行Agent_OnAttach,這里會創(chuàng)建一個Instrumentation實例并返回給用戶供大家擴(kuò)展Instrumentation,比如增加一些transform。并會執(zhí)行Instrumentation實例的loadClassAndCallAgentmain方法,該方法主要執(zhí)行agent的MF文件里定義的 Agent-Class類的agentmain方法,當(dāng)vm初始化完畢之后,會調(diào)用loadClassAndCallPremain方法,該方法主要執(zhí)行agent的MF文件里定義的 Agent-Class類的pre main方法。在類進(jìn)行加載的時候會調(diào)用Instrumentation的transform方法,可以看看參數(shù)里有個byte數(shù)組,這個數(shù)組其實就是正在加載的class字節(jié)碼,所以如果要字節(jié)碼增強(qiáng)在這里就可以入手啦,甚至可以實現(xiàn)偷天換日.
          posted @ 2013-04-12 22:38 你假笨 閱讀(2206) | 評論 (0)編輯 收藏
                 本文最初發(fā)表在http://www.lovestblog.cn,轉(zhuǎn)載請注明出處,謝謝。
           最近在忙一個項目,使用的是Flex+Spring+Hibernate,期間碰到一個問題,有必要在此記錄一下,也方便有相似問題的來者參考下
                  問題描述:有一個用戶表和一個用戶詳情表,這兩個表是一個一對一的單向關(guān)聯(lián)關(guān)系,即在用戶表中一個外鍵引用用戶詳情表,我在UserInfo的映射文件中使用的是many-to-one,設(shè)置了unique="true"表示一對一關(guān)系,設(shè)置了cascade="save-update"表示的是在保存useInfo對象的時候會自動保存與之關(guān)聯(lián)的userDetails臨時對象,即我希望的是先執(zhí)行一個在用戶詳情表中的插入語句然后再執(zhí)行一個在用戶表中的插入語句,userInfo對象是從flex端傳過來的,當(dāng)然也設(shè)置了userDetails屬性的值,在userInfo的dao文件中save方法是這樣的
              public IvUserInfo save(IvUserInfo transientInstance) {
                  log.debug(
          "saving IvUserInfo instance");
                  
          try {
                      getHibernateTemplate().save(transientInstance);
                      log.debug(
          "save successful");
                  } 
          catch (RuntimeException re) {
                      log.error(
          "save failed", re);
                      
          throw re;
                  }
                  
          return transientInstance;
              }
          后面發(fā)現(xiàn)執(zhí)行的sql語句只有一條插入語句,就是在用戶表中的一個插入,由于外鍵的關(guān)聯(lián)作用,是用戶表的這條插入也無法執(zhí)行,這就是問題所在了。
                  問題解決:這個問題我也沒有具體研究Hibernate的源碼,我先寫了個測試類,發(fā)現(xiàn)僅僅在java中執(zhí)行操作的話是可以正確執(zhí)行兩條插入語句的,但是通過flex傳過來就有問題了,那說明是flex端傳參數(shù)過來的問題,于是我試著修改UserInfo的save方法:

          public IvUserInfo save(IvUserInfo transientInstance) {
                  log.debug(
          "saving IvUserInfo instance");
                  
          try {
                      IvUserDetails ud
          =new IvUserDetails();
                      ud.setQq(transientInstance.getIvUserDetails().getQq());

                      transientInstance.setIvUserDetails(ud);
                      getHibernateTemplate().save(transientInstance);
                      log.debug(
          "save successful");
                  } 
          catch (RuntimeException re) {
                      log.error(
          "save failed", re);
                      
          throw re;
                  }
                  
          return transientInstance;
              }
          這樣一來問題解決了,順利執(zhí)行了兩條插入語句。
                 如果朋友知道具體原因的話希望給我留言了,同時也希望該記錄能幫助碰到此類問題的朋友。
          posted @ 2010-06-22 11:20 你假笨 閱讀(1576) | 評論 (0)編輯 收藏
          主站蜘蛛池模板: 隆德县| 同心县| 闸北区| 寻乌县| 平原县| 陆丰市| 苏尼特左旗| 新晃| 婺源县| 册亨县| 邢台县| 永泰县| 陈巴尔虎旗| 栖霞市| 婺源县| 滦平县| 精河县| 来宾市| 赣州市| 西丰县| 朝阳区| 庆阳市| 仪陇县| 阳城县| 吴旗县| 翁源县| 苗栗县| 儋州市| 嘉义县| 鄂伦春自治旗| 大宁县| 巴东县| 三原县| 孟连| 莱阳市| 临澧县| 随州市| 南岸区| 镇安县| 开阳县| 灵台县|