<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      阿里一面:類加載的過程是怎么樣的? 雙親委派的優(yōu)點和缺點? 產(chǎn)生fullGC的情況有哪些? spring的動態(tài)代理有哪些?區(qū)別是什么? 如何排查CPU使用率過高?

      摘要

      A公司的面經(jīng)

      • JVM的類加載的過程是怎么樣的?
      • 雙親委派模型的優(yōu)點和缺點?
      • 產(chǎn)生fullGC的情況有哪些?
      • spring的動態(tài)代理有哪些?區(qū)別是什么?
      • 如何排查CPU使用率過高?

      JVM的類加載的過程是怎么樣的?

      這個問題有些抽象,是指要說出具體步驟,還是要深入每一步的細(xì)節(jié)?再次確認(rèn)一下范圍,給出的回答是,你自己了解多少就說多少。這就有意思,那我就憑自己的語言進(jìn)行總結(jié)發(fā)揮了。

      簡述

      類加載,是指JVM將.class文件的數(shù)據(jù)加載到內(nèi)存中,并進(jìn)行校驗、解析以及初始化等一系列操作后,最終生成可被JVM直接使用的數(shù)據(jù)的過程。

      解釋

      我們知道一個類在JVM的生命周期大致可以分為7個階段:加載、驗證、準(zhǔn)備、解析、初始化、使用、卸載。
      類加載的過程,主要就是類生命周期的前5個階段,所以類加載的主要步驟為:
      加載、驗證、準(zhǔn)備、解析、初始化。
      因為【驗證】、【準(zhǔn)備】、【解析】有時候被統(tǒng)一稱為鏈接階段,因此有時候類加載也會被分三個步驟:加載、鏈接、初始化
      image

      加載(Loading)

      第一步,加載,主要是通過類的全限定名(如:java.lang.String)獲取類的二進(jìn)制字節(jié)流,將字節(jié)流轉(zhuǎn)換為JVM運行時的數(shù)據(jù)結(jié)構(gòu),在堆中生成一個 java.lang.Class 對象,作為該類的訪問入口。
      觸發(fā)方式:

      • ClassLoader.getSystemClassLoader().loadClass("com.jimoer.Test")
      • Class.forName("com.jimoer.Test") // 加載并初始化
      • 創(chuàng)建實例(new Test())、調(diào)用靜態(tài)方法或訪問靜態(tài)字段。

      驗證(Verification)

      主要是校驗,.class文件的正確性。
      校驗類的正確性(文件格式,元數(shù)據(jù),字節(jié)碼,二進(jìn)制兼容性),保證類的結(jié)構(gòu)符合JVM規(guī)范。

      準(zhǔn)備(Preparation)

      為類的 靜態(tài)變量(static 字段)分配內(nèi)存并設(shè)置 默認(rèn)值
      這里只初始化類變量,即static變量,所以都是在方法區(qū)里面進(jìn)行分配內(nèi)存的。而實例變量是會在對象實例化的時候進(jìn)行初始化的,并在Java堆里分配內(nèi)存。

      解析(Resolution)

      將常量池中的 符號引用 轉(zhuǎn)換為 直接引用。
      把類的符號引用轉(zhuǎn)為直接引用(類或接口、字段、類方法、接口方法、方法類型、方法句柄和訪問控制修飾符7類符號引用)。

      初始化(Initialization)

      執(zhí)行類的 初始化邏輯(即 <clinit>() 方法),完成靜態(tài)變量賦值和靜態(tài)代碼塊的執(zhí)行。

      public class ClassInit {
          static int a = 10; // 準(zhǔn)備階段:a = 0;初始化階段:a = 10
          static {
              a = 20; // 最終 a = 20
          }
      }
      

      雙親委派模型的優(yōu)點和缺點?

      Java應(yīng)用是由 啟動類加載器(Bootstrap Class Loader)、擴(kuò)展類加載器(Extension Class Loader)、應(yīng)用程序類加載器(Application Class Loader),這三類加載器互相配合來完成加載的,如果有自定義的類加載器,會先執(zhí)行自定義的類加載器。
      各種的類加載器之間的層次關(guān)系被稱為類加載器的“雙親委派模型(Parents Delegation Model)”。
      image

      雙親委派模型要求除了頂層的啟動類加載器外,其余的類加載器都應(yīng)有自己的父類加載器。

      雙親委派模型的工作過程

      如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,每一個層次的類加載器都是如此,因此所有的加載請求最終都應(yīng)該傳送到最頂端的啟動類加載器中,只有當(dāng)父加載器反饋自己無法完成這個加載請求(它的搜索范圍中沒有找到所需的類)時,子加載才會嘗試自己去完成加載。

      雙親委派模型的優(yōu)點

      1. 避免類的重復(fù)加載。確保了不同類加載器加載的相同類是同一個實例,避免類型沖突(如java.lang.Object的唯一性)。
      2. 防止惡意代碼篡改核心類,以及避免因類版本不一致導(dǎo)致的兼容性問題。例如,攻擊者無法通過自定義類加載器替換java.lang.String為惡意實現(xiàn),從而保障JVM運行安全。
      3. 提高類加載效率。通過層級委托機(jī)制,減少重復(fù)搜索類路徑(ClassPath)的次數(shù)。類加載器只需嘗試一次父類加載器的加載,若失敗再自行加載,避免了全盤掃描,提升性能。

      雙親委派模型的缺點

      1. 限制自定義類的動態(tài)更新。一旦類被父類加載器加載(如BootStrapClassLoader),即使類文件被修改,子類加載器也無法重新加載該類。
        場景:
        在熱部署(Hot Deployment)或插件化系統(tǒng)中,需要動態(tài)更新類時,雙親委派機(jī)制會阻礙實現(xiàn)。
        解決方案
        打破雙親委派機(jī)制:通過自定義類加載器繞過父類加載器,直接加載新版本類(例如Tomcat的WebAppClassLoader)。
        使用模塊化框架:如OSGi,通過隔離類加載器實現(xiàn)模塊的獨立更新。
      2. 子類加載器加載的類無法被父類加載器訪問(單向依賴)。
        場景
        在分布式系統(tǒng)中,可能需要跨類加載器共享數(shù)據(jù),但父類加載器無法直接調(diào)用子類加載器加載的類。
        解決方案
        通過接口或抽象類設(shè)計:將公共方法定義為接口,由父類加載器加載接口,子類加載器實現(xiàn)具體邏輯。
        使用共享類路徑:將需要共享的類放在父類加載器的類路徑中。
      3. 類的可見性受限
        子類加載器加載的類無法被父類加載器訪問(單向依賴)。
        場景:
        在分布式系統(tǒng)中,可能需要跨類加載器共享數(shù)據(jù),但父類加載器無法直接調(diào)用子類加載器加載的類。
        解決方案:
        通過接口或抽象類設(shè)計:將公共方法定義為接口,由父類加載器加載接口,子類加載器實現(xiàn)具體邏輯。
        使用共享類路徑:將需要共享的類放在父類加載器的類路徑中。

      產(chǎn)生FullGC的情況有哪些?

      JVM觸發(fā)FullGC的情況比較復(fù)雜也比較多,這里只說一些常見的,不能保證包含了全部產(chǎn)生FullGC的情況。

      老年代空間不足

      老年代存儲空間不足

      當(dāng)老年代不足以容納新對象或新生代晉升的對象時,會觸發(fā) Full GC。
      大對象直接分配到老年代(通過 -XX:PretenureSizeThreshold 閾值)。
      Survivor 區(qū)無法容納所有存活對象(擔(dān)保機(jī)制觸發(fā)晉升到老年代)。

      老年代連續(xù)空間不足

      即使老年代總空間足夠,但碎片化嚴(yán)重(如大量小對象釋放后未合并),無法分配大對象時,也會觸發(fā) Full GC。

      元空間內(nèi)存不足

      當(dāng)元空間(Metaspace)存儲類元數(shù)據(jù)的空間不足時,JVM 會嘗試通過 Full GC 回收無用的類元數(shù)據(jù)(如卸載不再使用的類)。
      若仍不足,則拋出 OutOfMemoryError: Metaspace。

      System.gc() 被顯式調(diào)用

      顯式調(diào)用 System.gc() 會請求 JVM 執(zhí)行 Full GC(可通過 -XX:+DisableExplicitGC 禁用)。

      OOM 前的最后嘗試

      當(dāng)內(nèi)存不足錯誤(OOM)觸發(fā)。
      當(dāng) JVM 即將拋出 OutOfMemoryError(如堆內(nèi)存不足 Java heap space 或元空間不足 Metaspace)時,會嘗試通過 Full GC 回收垃圾,若仍失敗則拋出 OOM。

      自適應(yīng)內(nèi)存管理策略

      若 JVM 的自適應(yīng)內(nèi)存管理(如 -XX:+UseAdaptiveSizePolicy)動態(tài)調(diào)整堆內(nèi)存時發(fā)現(xiàn)內(nèi)存緊張,可能觸發(fā) Full GC 重新平衡內(nèi)存布局。

      分布式緩存框架主動觸發(fā)

      某些分布式緩存框架(如 Ehcache、Redis Java 客戶端)在檢測到堆內(nèi)存占用過高時,會主動觸發(fā) Full GC 回收緩存對象。
      然而這種做法需謹(jǐn)慎使用,可能導(dǎo)致性能問題,可能引發(fā)性能抖動甚至 STW(Stop-The-World)時間過長。

      其他特殊場景

      內(nèi)存泄漏

      未被正確釋放的對象(如未關(guān)閉數(shù)據(jù)庫連接、線程池未關(guān)閉、ThreadLocal 未 remove())導(dǎo)致老年代持續(xù)增長,最終觸發(fā) Full GC。

      晉升年齡閾值過低

      若新生代對象晉升到老年代的年齡閾值(-XX:MaxTenuringThreshold)設(shè)置過小,對象過早進(jìn)入老年代,可能加速老年代空間耗盡。

      Spring使用的動態(tài)代理有哪些?區(qū)別是什么?

      Spring框架中主要使用兩種動態(tài)代理技術(shù):JDK動態(tài)代理CGLIB動態(tài)代理。

      JDK動態(tài)代理

      基于接口實現(xiàn):通過Java自帶的 java.lang.reflect.Proxy 類動態(tài)生成代理類,代理類會實現(xiàn)目標(biāo)類所實現(xiàn)的所有接口。
      通過反射調(diào)用目標(biāo)方法(Method.invoke()),性能相對較低。

      適用場景

      目標(biāo)類實現(xiàn)了至少一個接口(如Service層接口)。
      適用于需要兼容接口擴(kuò)展性的場景。

      優(yōu)點

      代碼簡潔:無需引入額外依賴。
      兼容性強(qiáng):適合有接口的設(shè)計模式。

      缺點

      局限性:目標(biāo)類必須實現(xiàn)接口,否則無法使用。
      性能問題:基于反射調(diào)用,性能較低(尤其是高頻調(diào)用時)。
      無法獲取實現(xiàn)類方法上的注解:當(dāng)目標(biāo)類實現(xiàn)接口時,代理對象可能無法直接獲取實現(xiàn)類方法上的注解。

      CGLIB動態(tài)代理

      通過CGLIB庫(Code Generation Library)動態(tài)生成目標(biāo)類的子類,重寫方法實現(xiàn)代理
      直接調(diào)用父類方法(非反射),性能較高。
      需要引入CGLIB庫(如 cglib 或 spring-core)。
      spring-boot現(xiàn)在默認(rèn)是使用CGLIB動態(tài)代理。

      適用場景

      目標(biāo)類未實現(xiàn)任何接口(如Controller層或第三方類)。
      需要代理final類或方法以外的普通類

      優(yōu)點

      靈活性高:無需目標(biāo)類實現(xiàn)接口。
      性能更高:直接調(diào)用方法,避免反射開銷。
      支持更復(fù)雜的代理需求:如代理無接口類。

      缺點

      依賴第三方庫:需要引入CGLIB依賴
      限制:無法代理final類或final方法(因為無法繼承和重寫)
      生成代理類較慢:字節(jié)碼生成過程比JDK動態(tài)代理稍慢。

      如何排查CPU使用率過高?

      首先登錄到服務(wù)器上,看一下具體情況。

      定位進(jìn)程

      登錄服務(wù)器,執(zhí)行top命令,查看CPU占用情況。

      PID    COMMAND      %CPU  TIME     #TH   #WQ  #PORT MEM    PURG   CMPRS  PGRP  PPID  STATE
      41846  java        130.4  04:36:58 14/1  5    1695+ 618M-  6356K  99M-   41846 1     running
      18122  top          7.5   00:04.68 1/1   0    32    4872K  0B     0B     18122 18106 running
      
      

      通過Top命令,可以看到,占用CPU最高的是PID為41846的這個java進(jìn)程。

      定位線程

      由于 Java 程序是單進(jìn)程多線程模型,因此需要進(jìn)一步定位具體是哪個線程的CPU占用最高。
      同樣是使用top命令:top -Hp 41846

      PID    COMMAND   %CPU TIME     #TH  #WQ  #POR MEM   PURG CMPRS PGRP  PPID
      19327  java       130  00:12.59 30   1    141  154M  0B   123M- 41846 41846
      

      top -Hp 41846命令可以看到,當(dāng)前進(jìn)程下,線程ID為19327的占用CPU最高。

      定位代碼

      首先將線程ID轉(zhuǎn)成16進(jìn)制

      printf '%x\n' 19327
      
      4b7f
      

      接下來就可以通過jstack來查看棧信息

      jstack 41846 |grep -A 200 4b7f
      
      "main" #1 prio=5 os_prio=0 tid=0x00007f8a8c000000 nid=0x3048 runnable [0x00007f8a9c000000]
         java.lang.Thread.State: RUNNABLE
      	at com.jimoer.app.CPUSpikeDemo.simulation(CPUSpikeDemo.java:12)
      	at com.jimoer.app.CPUSpikeDemo.main(CPUSpikeDemo.java:18)
      

      通過輸出的棧信息日志,可以看到,是CPUSpikeDemo這個類的第18行可能有問題。

      posted @ 2025-09-18 17:36  紀(jì)莫  閱讀(70)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久精品一区二区日韩av| 999精品全免费观看视频| 爱情岛亚洲论坛成人网站| 国产视频 视频一区二区| 男人j进入女人j内部免费网站| 国产片av在线观看国语| 日韩精品一区二区三区视频| 日韩丝袜人妻中文字幕| 国产成人精品无人区一区| 国产毛片三区二区一区| 久操资源站| 亚洲区精品区日韩区综合区| 撕开奶罩揉吮奶头高潮av| 麻豆天美东精91厂制片| 怀安县| 国产激情一区二区三区不卡| 制服丝袜美腿一区二区| 野外做受三级视频| 男女性高爱潮免费网站| 伊人久久精品一区二区三区| 天干天干啦夜天干天2017| 精品中文字幕一区在线| 国产精品一品二区三四区| 香港特级三A毛片免费观看| 国产精品99久久久久久www| 国产一级片内射在线视频| 免费看黄色亚洲一区久久| 午夜天堂一区人妻| 九九热在线免费观看视频| 亚洲日韩性欧美中文字幕| 人妻中文字幕不卡精品| 中文字幕日韩熟女av| 人妻丝袜AV中文系列先锋影音| 婷婷99视频精品全部在线观看 | 国产一区二区午夜福利久久| 国产线播放免费人成视频播放| 好紧好湿太硬了我太爽了视频| free性开放小少妇| 天天做天天爱夜夜爽导航 | 亚洲人成电影网站色mp4| 亚洲人成人一区二区三区|