<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>

          0.07 秒啟動(dòng)一個(gè) SpringBoot 項(xiàng)目!

          共 9027字,需瀏覽 19分鐘

           ·

          2021-11-08 12:28

          寫一段簡(jiǎn)單的 Java 程序。

          public?class?Hello?{
          ????public?static?void?main(String[]?args)?{
          ?????????System.out.println("hello?world");
          ????}
          }
          通常我們想運(yùn)行它要這樣。
          [root@flash?~]#?javac?Hello.java
          [root@flash?~]#?java?Hello
          hello?world
          但運(yùn)行起來(lái)需要 jre

          我們換一種方式來(lái)編譯這個(gè)程序,首先下載一個(gè) GraalVM 的 native-image 工具,然后。
          [root@flash?~]#?native-image?Hello
          [hello:11725]????classlist:???1,031.19?ms,??0.96?GB
          [hello:11725]????????(cap):???2,624.14?ms,??0.96?GB
          [hello:11725]????????setup:???3,960.95?ms,??0.96?GB
          [hello:11725]?????(clinit):?????288.49?ms,??1.72?GB
          [hello:11725]???(typeflow):???2,642.38?ms,??1.72?GB
          [hello:11725]????(objects):???3,803.54?ms,??1.72?GB
          [hello:11725]???(features):???1,176.79?ms,??1.72?GB
          [hello:11725]?????analysis:???8,288.82?ms,??1.72?GB
          [hello:11725]?????universe:?????909.14?ms,??1.75?GB
          [hello:11725]??????(parse):?????801.67?ms,??1.75?GB
          [hello:11725]?????(inline):???1,096.07?ms,??2.32?GB
          [hello:11725]????(compile):???7,352.50?ms,??2.37?GB
          [hello:11725]??????compile:??10,146.59?ms,??2.37?GB
          [hello:11725]????????image:???1,639.93?ms,??2.37?GB
          [hello:11725]????????write:?????682.24?ms,??2.37?GB
          [hello:11725]??????[total]:??26,855.67?ms,??2.37?GB
          #?Printing?build?artifacts?to:?.../hello.build_artifacts.txt
          執(zhí)行完這個(gè)命令后,發(fā)現(xiàn)當(dāng)前目錄多了個(gè) hello 文件。

          直接執(zhí)行它,可以成功!
          [root@flash?~]#?./hello
          hello?world
          而且注意,這個(gè)是可以直接以二進(jìn)制形式運(yùn)行的,不依賴 jre。
          ?
          也就是說(shuō),一個(gè) Java 程序,被這個(gè) native-image 編譯成了本地代碼!
          ?
          這項(xiàng)技術(shù)來(lái)自于 GraalVM 的一個(gè)特性,在其官網(wǎng)的文檔中可以了解到,GraalVM 主要有三大特性:
          ?
          1. 通過(guò)新的 JIT 技術(shù)使 Java 程序更快運(yùn)行
          2. 多語(yǔ)言支持
          3. 構(gòu)建 JVM 無(wú)關(guān)的本地鏡像
          ?
          這個(gè) native-image 技術(shù)就是其中的第三點(diǎn),即將 Java 代碼編譯成 JVM 無(wú)關(guān)的本地鏡像,使其可以直接以二進(jìn)制的方式運(yùn)行起來(lái)。
          ?
          除了運(yùn)行方便之外,我們對(duì)比一下這倆的文件大小啟動(dòng)時(shí)間
          [root@flash?~]#?ll
          -rw-r--r--??1?flash??staff???415B?10?27?15:50?Hello.class
          -rwxr-xr-x??1?flash??staff????
          10M?10?27?15:51?hello

          [root@flash?~]#?time?java?Hello
          hello?world
          java?Hello??0.09s?user?0.03s?system?113%?cpu?0.106?total

          [root@flash?~]#?time?./hello
          hello?world
          ./hello??0.00s?user?0.01s?system?34%?cpu?0.032?total
          總結(jié)個(gè)表格。

          Hello.class??415B? 0.12s
          hello? 10M? 0.01s

          可以看出,啟動(dòng)時(shí)間大大縮短了!但文件大小卻大大增加了。
          ?
          不過(guò)要知道,運(yùn)行 Hello.class 要整個(gè) jre 的支持,而運(yùn)行二進(jìn)制的 hello 卻不需要,這部分文件大小的差距,在小代碼上對(duì)比并不公平。
          ?
          當(dāng)然,啟動(dòng)時(shí)間也都是毫秒級(jí)的,差距也不足以說(shuō)明問(wèn)題。下面我們?cè)囍眠@種方式,對(duì)比一個(gè) Spring Boot 項(xiàng)目。
          ?
          有一點(diǎn)要說(shuō)明的是,GraalVM 的本地編譯對(duì) Java 代碼有很多的限制,有的時(shí)候需要配合配置文件才能成功,比如不支持動(dòng)態(tài)類加載、反射、序列化等,具體可以見(jiàn)這里:

          https://www.GraalVM.org/reference-manual/native-image/Limitations/

          可是 Spring 項(xiàng)目中可是大量充斥著這些,我們需要增加好多配置文件,才能成功本地編譯一個(gè) Spring Boot 項(xiàng)目。
          ?
          好在,Spring 已經(jīng)為我們考慮好這些事情了,提供了一個(gè)專門為 native 而生的 Spring Boot 依賴項(xiàng),最方便的是我們新建項(xiàng)目的時(shí)候可以直接從 start.spring.io 生成。
          ?
          ?
          然后可以直接用 mvn 命令來(lái)打包一個(gè)本地鏡像。
          [root@flash?~]#?mvn?package?-Pnative
          ...
          [INFO]?Executing:?...native-image?-cp?...?-H:Name=demo-1
          ...
          [demo-1:7725]????classlist:???1,695.81?ms,??0.94?GB
          [demo-1:7725]????????(cap):???1,932.48?ms,??0.94?GB
          [demo-1:7725]????????setup:???3,287.65?ms,??0.94?GB
          [demo-1:7725]?????(clinit):???2,256.61?ms,??5.68?GB
          [demo-1:7725]???(typeflow):??18,462.41?ms,??5.68?GB
          [demo-1:7725]????(objects):??17,848.47?ms,??5.68?GB
          [demo-1:7725]???(features):???4,646.24?ms,??5.68?GB
          [demo-1:7725]?????analysis:??45,521.71?ms,??5.68?GB
          [demo-1:7725]?????universe:???2,624.03?ms,??5.68?GB
          [demo-1:7725]??????(parse):???1,917.71?ms,??5.68?GB
          [demo-1:7725]?????(inline):???6,021.71?ms,??5.93?GB
          [demo-1:7725]????(compile):??30,497.99?ms,??6.06?GB
          [demo-1:7725]??????compile:??42,184.66?ms,??6.06?GB
          [demo-1:7725]????????image:???8,700.31?ms,??5.90?GB
          [demo-1:7725]????????write:???1,647.51?ms,??5.90?GB
          [demo-1:7725]??????[total]:?106,412.95?ms,??5.90?GB
          #?Printing?build?artifacts?to:?.../demo-1.build_artifacts.txt
          同樣,我們用傳統(tǒng)的 jar 包方式打包一個(gè) jar 文件,對(duì)比一下。
          -rwxr-xr-x??1?flash??staff????66M?Nov??2?16:11?demo-1
          -rw-r--r--??1?flash??staff????17M?Nov??2?16:09?demo-1-exec.jar
          這回大小已經(jīng)沒(méi)差那么多了,但仍然是二進(jìn)制的本地包大。不過(guò)這僅僅是幾乎空的 Spring Boot 項(xiàng)目,隨著項(xiàng)目依賴的包越來(lái)越多,二進(jìn)制的文件大小會(huì)越來(lái)越有優(yōu)勢(shì),這是后話了。
          ?
          我們?cè)賮?lái)對(duì)比一下啟動(dòng)速度,首先是傳統(tǒng)的 jar 包運(yùn)行。
          [root@flash?~]#?java?-jar?demo-1-exec.jar?


          ??.???____??????????_????????????__?_?_
          ?/\\?/?___'_?__?_?_(_)_?__??__?_?\?\?\?\
          (?(?)\___?|?'
          _?|?'_|?|?'_?\/?_`?|?\?\?\?\
          ?\\/??___)|?|_)|?|?|?|?|?||?(_|?|??)?)?)?)
          ??'??|____|?.__|_|?|_|_|?|_\__,?|?/?/?/?/
          ?=========|_|==============|___/=/_/_/_/
          ?::?Spring?Boot?::????????????????(v2.5.6)


          2021-11-02?16:36:11.192??INFO?9468?---?[main]?com.example.demo1.Demo1Application???????:?Starting?Demo1Application?v0.0.1-SNAPSHOT?using?Java?11.0.12?on?sunyiming07deMacBook-Pro.local?with?PID?9468?(/Users/sunyiming07/IdeaProjects/graalvm-demos/springboot/demo/demo-1/target/demo-1-0.0.1-SNAPSHOT-exec.jar?started?by?sunyiming07?in?/Users/sunyiming07/IdeaProjects/graalvm-demos/springboot/demo/demo-1/target)
          2021-11-02?16:36:11.195??INFO?9468?---?[main]?com.example.demo1.Demo1Application???????:?No?active?profile?set,?falling?back?to?default?profiles:?default
          2021-11-02?16:36:12.097??INFO?9468?---?[main]?o.s.b.w.embedded.tomcat.TomcatWebServer??:?Tomcat?initialized?with?port(s):?8080?(http)
          2021-11-02?16:36:12.110??INFO?9468?---?[main]?o.apache.catalina.core.StandardService???:?Starting?service?[Tomcat]
          2021-11-02?16:36:12.110??INFO?9468?---?[main]?org.apache.catalina.core.StandardEngine??:?Starting?Servlet?engine:?[Apache?Tomcat/9.0.54]
          2021-11-02?16:36:12.164??INFO?9468?---?[main]?o.a.c.c.C.[Tomcat].[localhost].[/]???????:?Initializing?Spring?embedded?WebApplicationContext
          2021-11-02?16:36:12.164??INFO?9468?---?[main]?w.s.c.ServletWebServerApplicationContext?:?Root?WebApplicationContext:?initialization?completed?in?917?ms
          2021-11-02?16:36:12.484??INFO?9468?---?[main]?o.s.b.w.embedded.tomcat.TomcatWebServer??:?Tomcat?started?on?port(s):?8080?(http)?with?context?path?''
          2021-11-02?16:36:12.494??INFO?9468?---?[main]?com.example.demo1.Demo1Application???????:?Started?Demo1Application?in?2.033?seconds?(JVM?running?for?2.504)
          2.033 秒,已經(jīng)慢下來(lái)了,不過(guò)正常的空 Spring Boot 項(xiàng)目也就這樣。
          ?
          再看看本地鏡像啟動(dòng)速度。
          [root@flash?~]#?./demo-1
          2021-11-02?16:38:33.141??INFO?9724?---?[main]?o.s.nativex.NativeListener???????????????:?This?application?is?bootstrapped?with?code?generated?with?Spring?AOT


          ??.???____??????????_????????????__?_?_
          ?/\\?/?___'_?__?_?_(_)_?__??__?_?\?\?\?\
          (?(?)\___?|?'
          _?|?'_|?|?'_?\/?_`?|?\?\?\?\
          ?\\/??___)|?|_)|?|?|?|?|?||?(_|?|??)?)?)?)
          ??'??|____|?.__|_|?|_|_|?|_\__,?|?/?/?/?/
          ?=========|_|==============|___/=/_/_/_/
          ?::?Spring?Boot?::????????????????(v2.5.6)


          2021-11-02?16:38:33.143??INFO?9724?---?[main]?com.example.demo1.Demo1Application???????:?Starting?Demo1Application?v0.0.1-SNAPSHOT?using?Java?11.0.12?on?sunyiming07deMacBook-Pro.local?with?PID?9724?(/Users/sunyiming07/IdeaProjects/graalvm-demos/springboot/demo/demo-1/target/demo-1?started?by?sunyiming07?in?/Users/sunyiming07/IdeaProjects/graalvm-demos/springboot/demo/demo-1/target)
          2021-11-02?16:38:33.143??INFO?9724?---?[main]?com.example.demo1.Demo1Application???????:?No?active?profile?set,?falling?back?to?default?profiles:?default
          2021-11-02?16:38:33.178??INFO?9724?---?[main]?o.s.b.w.embedded.tomcat.TomcatWebServer??:?Tomcat?initialized?with?port(s):?8080?(http)
          2021-11-02?16:38:33.178??INFO?9724?---?[main]?o.apache.catalina.core.StandardService???:?Starting?service?[Tomcat]
          2021-11-02?16:38:33.178??INFO?9724?---?[main]?org.apache.catalina.core.StandardEngine??:?Starting?Servlet?engine:?[Apache?Tomcat/9.0.54]
          2021-11-02?16:38:33.184??INFO?9724?---?[main]?o.a.c.c.C.[Tomcat].[localhost].[/]???????:?Initializing?Spring?embedded?WebApplicationContext
          2021-11-02?16:38:33.184??INFO?9724?---?[main]?w.s.c.ServletWebServerApplicationContext?:?Root?WebApplicationContext:?initialization?completed?in?41?ms
          2021-11-02?16:38:33.204??INFO?9724?---?[main]?o.s.b.w.embedded.tomcat.TomcatWebServer??:?Tomcat?started?on?port(s):?8080?(http)?with?context?path?''
          2021-11-02?16:38:33.204??INFO?9724?---?[main]?com.example.demo1.Demo1Application???????:?Started?Demo1Application?in?0.078?seconds?(JVM?running?for?0.08)
          我去!0.078 秒!!!
          ?
          我還真從來(lái)沒(méi)有啟動(dòng) Spring Boot 項(xiàng)目體驗(yàn)過(guò)這么極速的狀態(tài)呢!!!容我高興一會(huì)兒。
          ?
          看吧,前面的 hello world 項(xiàng)目看不出什么,現(xiàn)在的 Spring Boot 項(xiàng)目,優(yōu)勢(shì)就已經(jīng)完全出來(lái)了,啟動(dòng)速度秒殺呀!
          ?
          可想而知,我們?cè)瓉?lái)啟動(dòng)可能要幾分鐘才成功的 Spring Boot 項(xiàng)目,會(huì)被這個(gè) GraalVM 優(yōu)化到多少呢?想想就激動(dòng)!
          ?
          不過(guò)這個(gè)我還沒(méi)有試,光是跑這個(gè) Spring Boot 空項(xiàng)目就忙活了好久,一直報(bào)各種各樣奇怪的錯(cuò)誤,等我再熟練熟練的。
          ?
          剛剛也說(shuō)了,想通過(guò) GraalVM 的 native-image 功能編譯一個(gè) Java 程序,有很多限制,比如不支持動(dòng)態(tài)類加載、反射、動(dòng)態(tài)代理、JNI、序列化以及 invoke dynamic 指令等。
          ?
          這是由于,AOT 這種提前編譯的技術(shù),需要一個(gè)封閉空間假設(shè),即在編譯期就能夠把運(yùn)行期所有需要的東西都準(zhǔn)備好,但 Java 的好多特性就是和這種封閉空間假設(shè)相沖突的。

          Java 啟動(dòng)后隨著程序不斷運(yùn)行,JVM 將一部分代碼編譯成本地代碼,這個(gè)叫 JIT 技術(shù),它是在程序運(yùn)行起來(lái)之后不斷分析而做的編譯,所以它不受封閉空間假設(shè)的限制。
          ?
          說(shuō)回 GraalVM 的 AOT,比如程序中有個(gè)反射,這就屬于運(yùn)行時(shí)才會(huì)知道有這樣一個(gè) Student 類被需要的情況。
          Class.forName("com.flash.Student")
          當(dāng)然,GraalVM 會(huì)通過(guò)掃描這些反射方法的調(diào)用,來(lái)嘗試分析用到了哪些類。
          ?
          如果分析不出來(lái),就需要程序員手動(dòng)配置,告訴 GraalVM 有哪些類要反射。
          [
          ????{
          ????????name:?"com.flash.Student",
          ????????allDeclaredConstructors:?true,
          ????????allPublicMethods:?true
          ????},
          ????{
          ????????name:?"com.flash.Teacher",
          ????????fileds:?[{name:?"teach"},?{name:?"talk"}],
          ????????methods:?[{
          ????????????name:?"",
          ????????????parameterTypes:?["char[]"]
          ????????}]
          ????},
          ????//?……
          ]
          但這樣肯定是反人性的。
          ?
          自己寫的代碼和依賴還好,但如果是使用第三方組建,比如人人都用的 Spring,肯定不能由程序員來(lái)去寫這些配置文件。
          ?
          那就只有讓 Spring 官方提供這些配置,讓程序員仍然是簡(jiǎn)單寫一些 maven 依賴就能把項(xiàng)目跑起來(lái),才能把這個(gè)技術(shù)推廣出去,這也是剛剛 Spring Native 項(xiàng)目存在的意義。
          ?
          今天簡(jiǎn)單給大家分享下 GraalVM 的使用,這個(gè)技術(shù)基本還沒(méi)有公司大規(guī)模在用,還達(dá)不到工業(yè)級(jí)的成熟,不過(guò)未來(lái)云原生領(lǐng)域要求小包快速啟動(dòng)兩個(gè)特性,GraalVM 的未來(lái)說(shuō)不定有大舞臺(tái)呢。
          ?
          我也才剛剛開(kāi)始玩這個(gè)東西,很多地方還沒(méi)搞懂,所以很希望能有一個(gè)?GraalVM?專項(xiàng)討論群一起來(lái)學(xué)習(xí)和討論,不過(guò)一直沒(méi)找到。

          既然找不到那就自己建一個(gè)吧!如果有了解這個(gè)技術(shù)的,或者想要了解這個(gè)技術(shù)的,可以加我好友備注【graalvm拉你進(jìn)群,我們一起研討!

          瀏覽 69
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  jiZZJIZZ日本丰满熟妇 | 干干网| 日本黄色电影免费看网站 | 青青草偷拍视频 | 国产乱伦小说视频 |