【JVM】運行時數據區域

文章目錄

  • 1. 程序計數器
      • 補充
  • 2. 虛擬機棧
    • 2.1 棧幀
      • 1. 局部變量表
      • 2. 操作數棧
      • 3. 動態鏈接
      • 4. 方法返回地址
      • 補充
  • 3. 本地方法棧
  • 4. 堆
  • 5. 方法區
    • 靜態常量池(Class常量池)
    • 運行時常量池
    • 字符串常量池
      • (1)位置變化
      • (2)放入字符串常量池的3種途徑
        • 1. 字面量賦值
        • 2. new String("")
        • 3. **intern()**
        • 4. StringTable垃圾回收
        • 5. StringTable調優
    • 6. 直接內存
      • (1)概念
      • (2)特性
      • (3)管理與回收機制
        • 一、直接內存的分配與對象結構
        • 二、釋放流程
        • 三、關鍵機制深度解析
    • 其他
      • 1. 永久代為什么被替換為元空間

1. 程序計數器

(1)定義
一塊比較小的內存空間,可以看作是當前線程所執行的字節碼的行號指示器。

  • JVM解釋器通過程序計數器讀取下一條需要執行的字節碼指令。
  • 在Java虛擬機的概念模型里(代表了虛擬機的統一外觀,但各個Java虛擬機不一定一定要按照概念模型的定義來實現),字節碼解釋器的工作就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令。
  • 它是程序控制流的指示器,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器實現。

(2)特點

  • 線程私有
    內存隔離:程序計數器屬于線程私有內存
    作用:避免多線程競爭,確保線程獨立性。

  • 無OOM異常
    JVM規范未定義程序計數器的OOM(OutOfMemoryError)場景。
    因為它不占用堆或方法區,僅存儲當前指令的地址。

  • 占用較小內存
    僅保存一個指令地址(或Native方法的undefined),內存消耗可忽略。

  • 無垃圾回收
    不涉及對象存儲,無需GC管理。

補充

  1. 這個線程如果正在執行的是一個Java方法,那么這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;如果正在執行的是一個本地(Native)方法,這個計數器值應該為空

  2. 程序計數器是否可能為null?

    • Java方法執行時:始終指向有效指令地址
    • Native方法執行時:值為undefined,但不為null
  3. 工作流程:

    0: iload_1     // 加載局部變量1到操作數棧
    1: iload_2     // 加載局部變量2到操作數棧
    2: iadd        // 執行加法
    3: istore_3    // 將結果存儲到局部變量3
    
    • 當線程執行到iadd(地址2)時,程序計數器值為2。
    • 執行完iadd后,程序計數器自動更新為3,指向istore_3。

2. 虛擬機棧

(1)定義
用于存儲方法的調用和執行信息(保存方法的局部變量、操作數棧、動態鏈接、方法返回地址等)。每個方法調用對應一個棧幀(Stack Frame)。

虛擬機棧由一個個棧幀組成,每個方法在運行時,JVM都會同步創建一個棧幀,然后將棧幀壓入到虛擬機棧中。每次方法調用的數據都是通過棧傳遞的。

(2)異常

  • 棧內存溢出(棧幀過多或棧幀過大):StackOverflowError

    • 觸發條件:線程請求的棧深度超過JVM允許的最大深度(如無限遞歸調用)
    • 默認棧大小:不同JVM實現不同,HotSpot默認為1MB(可通過 -Xss 參數調整,如 -Xss256k
  • OutOfMemoryError

    • 觸發條件:如果Java虛擬機棧容量可以動態擴展,棧擴展時無法申請到足夠內存(如多線程場景下系統內存耗盡)

2.1 棧幀

每一個方法被調用到執行完畢的過程,就對應著一個棧幀在虛擬機棧中從入棧到出棧的過程。

每個棧幀存儲以下信息:

1. 局部變量表

存放的是編譯器可知的各種基本數據類型、對象引用和returnAddress類型。

  • A. 對象引用(reference類型,不等同于對象本身)
  • B. returnAddress類型(指向了一條字節碼指令的地址)

局部變量表的容量:以變量槽(Slot)為最小單位(32位類型占1個Slot,64位如long/double占2個Slot,其余的數據類型只占用1個)。

2. 操作數棧

用于執行字節碼指令的臨時數據存儲區(如算術運算、方法參數傳遞)。

i++ 和 ++i的區別:

  • i++:從局部變量表取出局部變量 i 并壓入操作棧后,對局部變量表中的 i 自增 1。線程取出使用操作數棧棧頂值的自增前的值。
  • ++i:先對局部變量表的 i 自增 1,然后取出并壓入操作棧,線程再從操作棧棧頂值取出自增之后的值使用。

3. 動態鏈接

4. 方法返回地址

方法退出的過程就是棧幀在虛擬機棧上的出棧過程,因此退出時的操作可能有:恢復上層方法的局部變量表和操作數棧,把返回值壓入調用者的操作數棧,每條整pc計數器的值指向調用該方法的后一條指令。

補充

  1. 垃圾回收是否涉及棧內存?

    • 垃圾回收主要針對的是堆內存。棧內存的生命周期由方法調用和返回自動管理,因此不需要GC機制介入。
  2. 棧內存分配越大越好嗎?

    • 優點:較大的棧內存可以允許更深的遞歸調用和更復雜的調用棧
    • 缺點:每個線程占用更多內存,容易耗盡總內存資源
  3. 方法內的局部變量是否線程安全?

    • 通常線程安全,因為每個線程有獨立的棧空間。
    • 例外:若局部變量引用了可變對象并被多個線程共享,則需要同步控制。

3. 本地方法棧

(1)定義
本地方法棧(Native Method Stacks)與虛擬機棧所發揮的作用是非常相似的:

  • 虛擬機棧為虛擬機執行Java方法(也就是字節碼)服務
  • 本地方法棧則是為虛擬機使用到的本地(Native)方法服務

(2)作用
為 JVM 執行 Native 方法(非 Java 代碼實現的方法,如 C/C++ 編寫的 JNI 方法)提供內存空間。

(3)歸屬
線程私有,每個線程在創建時都會分配獨立的本地方法棧。

(4)棧合并
HotSpot 將虛擬機棧與本地方法棧合并,通過一個統一的棧結構管理。

(5)異常

  • StackOverflowError:棧深度超過 JVM 限制時拋出(如遞歸調用過深)
  • OutOfMemoryError:棧擴展失敗時拋出(如內存不足)

4. 堆

(1)定義
JVM 中最大的內存區域,用于存儲所有對象實例和數組(通過 new 關鍵字創建的對象)。
此內存區域的唯一作用就是存放對象實例

(2)歸屬
線程共享,所有線程均可訪問堆中的對象。

(3)生命周期
對象在堆中分配內存,由垃圾回收器(GC)自動回收(無顯式釋放)。

(4)異常

  • OutOfMemoryError:堆內存不足且無法擴展時拋出(如內存泄漏或對象過多)

(5)虛擬機棧
棧幀中存儲對象的引用(指向堆中的對象實例)。


5. 方法區

(1)定義
方法區是JVM規范中定義的邏輯內存區域,用于存儲類元數據、運行時常量池、靜態變量、即時編譯器(JIT)編譯后的代碼等數據。
(2)內容

  • 類元數據存儲:類名、父類、字段、方法、訪問修飾符等
  • 靜態變量:類級別的static變量直接存儲在方法區
  • JIT熱點代碼:編譯后的本地機器碼存儲在“代碼緩存”(Code Cache)
  • 運行時常量池:動態解析符號引用,支持運行時添加常量

(3)垃圾回收

  • 可以不實現垃圾回收
  • 回收目標主要是常量池類型卸載
  • 方法區無法滿足內存需求時拋出 OutOfMemoryError

靜態常量池(Class常量池)

(1)定義
每個Java類被編譯后形成的 .class 文件中包含常量池信息,用于存放編譯器生成的各種字面量和符號引用。

(2)位置
保存在編譯后的 .class 文件中。

(3)存儲內容

  1. 字面量

    • 文本字符串(用雙引號包裹的值)
    • 被聲明為final的常量
    • 基本數據類型值
    • null
  2. 符號引用

    • 類符號引用(完全限定名)
    • 字段/方法的名稱和描述符

運行時常量池

(1)定義
方法區的一部分,用于存儲類文件中的常量數據(字面量)和符號引用。

(2)位置

  • JDK 7 及之前:永久代(PermGen)
  • JDK 8 起:Metaspace

(3)作用

  • 內存優化:共享重復常量
  • 加速訪問:減少解析開銷

(4)來源

  • 編譯期字面量與符號引用
  • 運行期動態生成常量(如 String.intern()

(5)結構組成

  • 字符串常量池(JDK 7 起移至堆中)
  • 符號引用表

(6)關鍵特性

  • 字符串字面量直接引用池中對象,new String("a") 創建堆中新對象
  • intern() 可強制加入池(注意性能)
  • 包裝類常量池(如 Integer 緩存 -128~127)
  • 類加載時解析符號引用為直接引用

以下是不改動文章內容,僅轉換為 Markdown 格式后的結果:


字符串常量池

(1)位置變化

  • JDK 1.6及之前:作為運行時常量池的一部分,位于永久代。
  • JDK 1.7:從永久代分離,移動到堆內存中。
  • JDK 1.8及之后:仍保留在堆內存中。

(2)放入字符串常量池的3種途徑

1. 字面量賦值

直接存入常量池

  • 字符串變量拼接原理是 StringBuilder
  • 字符串常量拼接原理是編譯期優化
String s1 = "a"; // 延遲:運行到這一步才會放入串池
String s2 = "b";
String s3 = "ab";
String s4 = s1 + s2; // new StringBuilder().append(s1).append(s2).toString() 即 new String("ab")
String s5 = "a" + "b"; // javac在編譯器的優化
System.out.println(s3 == s4); // f
System.out.println(s3 == s5); // t

流程步驟:

  1. 檢查常量池:JVM 解析代碼時發現字面量 "abc",首先檢查字符串常量池中是否存在哈希值相同的字符串。
  2. 存在則復用:若池中存在 "abc"(通過 equals 確認內容相同),直接返回池中對象的引用(s1 和 s2 指向同一對象)。
  3. 不存在則創建:若池中無 "abc",在常量池中創建該字符串對象,并返回引用。

底層實現:

  • 字符串常量池本質是哈希表(StringTable),默認桶數為 60013(可通過 -XX:StringTableSize 調整)。
  • 哈希值由字符串內容計算,沖突時通過鏈表或紅黑樹處理。
2. new String(“”)

堆對象與池交互

String s3 = new String("abc");
String s4 = s3.intern();
System.out.println(s3 == s4); // JDK 7+ 中為 false(s4 指向池對象,s3 指向堆對象)

流程步驟:

  1. 堆中創建對象new String("abc") 會在堆中創建一個新的字符串對象。
  2. 處理字面量
    • 若字面量 "abc" 不在常量池中,JVM 先在池中創建 "abc",再將堆對象指向該字面量的字符數組。
    • 若池中已有 "abc",堆對象直接引用池中的字符數組(但堆對象本身是獨立實例)。
3. intern()
String s5 = new StringBuilder("ja").append("va").toString();
System.out.println(s5.intern() == s5); // JDK 7+ 輸出 true(池中無 "java" 時)

流程步驟(以 JDK 7+ 為例):

  1. 檢查常量池:調用 intern() 時,檢查池中是否存在與當前字符串內容相同的對象。
  2. 存在則返回引用:直接返回池中對象的引用。
  3. 不存在則駐留
    • JDK 1.8:將當前字符串對象自身的引用直接加入常量池,并返回這個引用。
    • JDK 1.6:在常量池中復制(也就是在永久代中創建一份新的字符串對象)后返回該副本的引用,這樣原來在堆中創建的字符串對象和常量池中的對象就不是同一個引用了。
4. StringTable垃圾回收
  • JDK6及之前:StringTable 位于永久代(PermGen),僅在 Full GC 時回收,且永久代空間有限,易導致 OutOfMemoryError。
  • JDK7及之后:StringTable 移至堆內存,隨堆的 Minor GC 或 Major GC 觸發回收,內存管理更靈活。
  • StringTable 中的字符串對象會參與垃圾回收,但其哈希表結構本身不受 GC 影響。

StringTable 的底層結構

  • 哈希表存儲:
    StringTable 本質是一個固定大小的哈希表(HashTable),采用數組 + 鏈表(或紅黑樹)結構,默認桶數為 60013(可通過 -XX:StringTableSize 調整)。
5. StringTable調優
  1. 調整哈希表桶數量

    • StringTable 底層由 HashTable 實現,其性能與桶(Bucket)數量直接相關。桶數量越大,哈希沖突概率越低,查詢效率越高。
    • 默認值:
      • JDK6及之前:1009(永久代)
      • JDK7+:60013(堆內存)
    • 調整桶數:-XX:StringTableSize=<size>(JDK8+最小值為 1009)
  2. 主動控制字符串入池(intern()方法)

    • 適用場景:大量重復字符串(如地址、配置項)通過 intern() 復用,減少堆內存占用。

      List<String> address = new ArrayList<>();
      address.add(line.intern());  // 入池后重復字符串引用同一對象
      

6. 直接內存

(1)概念

直接內存(Direct Memory)是 Java 通過 java.nio.ByteBuffer.allocateDirect() 分配的堆外內存,由操作系統直接管理,不屬于 JVM 運行時數據區,但可通過 JVM 參數 -XX:MaxDirectMemorySize 限制其大小。

(2)特性

  • 高性能:減少數據在 JVM 堆與操作系統內核之間的拷貝,適用于高頻 I/O 操作(如文件讀寫、網絡通信)。
  • 手動管理:內存分配和釋放需開發者控制,但通過 DirectByteBuffer 對象間接管理,實際回收依賴 JVM 垃圾回收機制和虛引用。
  • 零拷貝:支持直接與本地 I/O 交互,避免傳統 I/O 的雙緩沖區復制。

(3)管理與回收機制

一、直接內存的分配與對象結構
  1. 分配入口
    調用 ByteBuffer.allocateDirect() 時,底層通過 DirectByteBuffer 構造函數觸發內存分配:
    DirectByteBuffer(int cap) {super(...);// 通過 Unsafe 類分配直接內存long base = unsafe.allocateMemory(cap);unsafe.setMemory(base, cap, (byte) 0);// 創建 Cleaner 虛引用,綁定釋放邏輯cleaner = Cleaner.create(this, new Deallocator(base, cap));
    }
    
  2. 關鍵對象關系
    • DirectByteBuffer 對象:位于堆內存,作為直接內存的引用句柄。
    • Cleaner 對象:繼承自 PhantomReference,維護釋放內存的回調邏輯。
    • Deallocator 對象:實現 Runnable,最終調用 Unsafe.freeMemory() 釋放內存。
二、釋放流程

階段 1:DirectByteBuffer 對象被標記為不可達

  • 觸發條件:堆中的 DirectByteBuffer 對象不再被任何 GC Roots 引用(如局部變量失效、強引用置為 null)。
  • GC 掃描:在 Young GC 或 Full GC 時,垃圾回收器識別該對象為垃圾。

階段 2:Cleaner 虛引用入隊

  • 引用隊列:Cleaner 作為虛引用(PhantomReference),當 DirectByteBuffer 對象被回收時,JVM 將其關聯的 Cleaner 對象加入 ReferenceQueue
  • 內部線程處理:JVM 的 ReferenceHandler 線程(高優先級守護線程)監控該隊列,發現新加入的 Cleaner 對象后,觸發其清理邏輯。

階段 3:執行 Deallocator 釋放內存

  • 回調邏輯
    Cleaner 對象的 clean() 方法被調用,執行其綁定的 Deallocator.run()
    public void run() {if (address != 0) {// 調用 Unsafe 釋放內存unsafe.freeMemory(address);address = 0;}
    }
    
  • 內存釋放
    Unsafe.freeMemory() 直接向操作系統釋放對應的物理內存或虛擬內存。
三、關鍵機制深度解析
  1. 虛引用(PhantomReference)的作用
  2. 與 Finalizer 的區別
    • Finalizer 通過 finalize() 方法實現資源釋放,但存在執行延遲和不確定性。
    • Cleaner 使用虛引用 + ReferenceQueue,確保釋放邏輯更及時、更可靠。

避免內存泄漏:

  • 虛引用不阻止對象被回收(get() 始終返回 null),確保 DirectByteBuffer 對象可被正常 GC。
  1. 顯式 GC 的觸發問題
    • 若 JVM 啟動參數包含 -XX:+DisableExplicitGC,顯式調用 System.gc() 將失效,或者未顯式調用 System.gc() 且未觸發 Full GC,則 ByteBufferDirectByteBuffer 對象可能長期未被回收,導致直接內存未釋放。

其他

1. 永久代為什么被替換為元空間

  1. 永久代設置空間大小是很難確定的,因為可能某個實際的業務場景中有不斷的類加載等工作,但是元空間時使用本地內存,默認情況下是本地大小限制的。
  2. 類及方法的信息等比較難確定其大小,因此對于永久代的大小指定比較困難,太小容易出現永久代溢出,太大則容易導致老年代溢出。
  3. 字符串存在永久代中,容易出現性能問題和內存溢出。這些也是

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75779.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75779.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75779.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

day28圖像處理OpenCV

文章目錄 一、圖像預處理4 邊緣填充4.1 邊界復制&#xff08;BORDER_REPLICATE&#xff09;4.2 邊界反射&#xff08;BORDER_REFLECT&#xff09;4.3 邊界反射101&#xff08;BORDER_REFLECT_101&#xff09;4.4 邊界常數&#xff08;BORDER_CONSTANT&#xff09;4.5 邊界包裹&…

C++ Json-Rpc框架-3項目實現(2)

一.消息分發Dispatcher實現 Dispatcher 就是“消息分發中樞”&#xff1a;根據消息類型 MType&#xff0c;把消息派發給對應的處理函數&#xff08;Handler&#xff09;執行。 初版&#xff1a; #pragma once #include "net.hpp" #include "message.hpp"n…

C++算法優化實戰:破解性能瓶頸,提升程序效率

C算法優化實戰&#xff1a;破解性能瓶頸&#xff0c;提升程序效率 在現代軟件開發中&#xff0c;算法優化是提升程序性能的關鍵手段之一。無論是在高頻交易系統、實時游戲引擎&#xff0c;還是大數據處理平臺&#xff0c;算法的高效性直接關系到整體系統的性能與響應速度。C作…

【PostgreSQL教程】PostgreSQL 特別篇之 語言接口連接PHP

博主介紹:?全網粉絲22W+,CSDN博客專家、Java領域優質創作者,掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域? 技術范圍:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大數據、物聯網、機器學習等設計與開發。 感興趣的可…

山東大學軟件學院創新項目實訓開發日志(12)之將對話記錄保存到數據庫中

在之前的功能開發中&#xff0c;已經成功將deepseekAPI接口接入到springbootvue項目中&#xff0c;所以下一步的操作是將對話和消息記錄保存到數據庫中 在之前的開發日志中提到數據庫建表&#xff0c;所以在此刻需要用到兩個表&#xff0c;conversation表和message表&#xff…

Spring-注解編程

注解基礎概念 1.什么是注解編程 指的是在類或者方法上加入特定的注解(XXX) 完成特定功能的開發 Component public classXXX{} 2.為什么要講注解編程 1.注解開發方便 代碼簡潔 開發速度大大提高 2.Spring開發潮流 Spring2.x引入注解 Spring3.x完善注解 Springboot普及 推廣注解…

Dify智能體平臺源碼二次開發筆記(5) - 多租戶的SAAS版實現(2)

目錄 前言 用戶的查詢 controller層 添加路由 service層 用戶的添加 controller層 添加路由 service層-添加用戶 service層-添加用戶和租戶關系 驗證結果 結果 前言 完成租戶添加功能后&#xff0c;下一步需要實現租戶下的用戶管理。基礎功能包括&#xff1a;查詢租…

基于若依的ruoyi-vue-plus的nbmade-boot在線表單的設計(一)架構方面的設計

希望大家一起能參與我的新開源項目nbmade-boot: 寧波智能制造低代碼實訓平臺 主要目標是類似設計jeecgboot那樣的online表單功能,因為online本身沒有開源這部分代碼,而我設計這個是完全開源的,所以希望大家支持支持,開源不容易。 1、數據庫方面設計考慮 是在原來gen_table和…

WebFlux應用中獲取x-www-form-urlencoded數據的六種方法

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;精通Java編…

[Python基礎速成]1-Python規范與核心語法

本系列旨在快速掌握Python&#xff0c;實現能夠快速閱讀和理解 Python 代碼&#xff0c;并在可查閱語法的情況下進行 AI 學習。 本篇先了解一下Python基礎知識。 本篇內容較菜鳥教程有所刪減、方便快速構建大綱&#xff0c;且加入了PEP 8規范說明等有助于理解和編寫代碼的說明。…

農民劇團的春天與改變之路

楊天義&#xff0c;男&#xff0c;1966年9月生&#xff0c;中共黨員&#xff0c;江西省吉安市吉水縣水南農民劇團團長。 楊天義從廢品收購起家&#xff0c;憑借自身的努力和奮斗&#xff0c;自籌資金100余萬元建設了水南鎮的第一座影劇院&#xff0c;組建了江西省吉安市吉水縣…

python asyncio 的基本使用

1、引言 asyncio 是 Python 標準庫中的一個庫&#xff0c;提供了對異步 I/O 、事件循環、協程和任務等異步編程模型的支持。 asyncio 文檔 2、進程、線程、協程 線程 線程是操作系統調度的基本單位&#xff0c;同一個進程中的多個線程共享相同的內存空間。線程之間的切換由操…

Leedcode刷題 | Day30_貪心算法04

一、學習任務 452. 用最少數量的箭引爆氣球代碼隨想錄435. 無重疊區間763. 劃分字母區間 二、具體題目 1.452用最少數量的箭引爆氣球452. 用最少數量的箭引爆氣球 - 力扣&#xff08;LeetCode&#xff09; 在二維空間中有許多球形的氣球。對于每個氣球&#xff0c;提供的輸…

Ant Design Vue 表格復雜數據合并單元格

Ant Design Vue 表格復雜數據合并單元格 官方合并效果 官方示例 表頭只支持列合并&#xff0c;使用 column 里的 colSpan 進行設置。 表格支持行/列合并&#xff0c;使用 render 里的單元格屬性 colSpan 或者 rowSpan 設值為 0 時&#xff0c;設置的表格不會渲染。 <temp…

C++ 標準庫中的 <algorithm> 頭文件算法總結

C 常用 <algorithm> 算法概覽 C 標準庫中的 <algorithm> 頭文件提供了大量有用的算法&#xff0c;主要用于操作容器&#xff08;如 vector, list, array 等&#xff09;。這些算法通常通過迭代器來操作容器元素。 1. 非修改序列操作 std::all_of, std::any_of, s…

程序化廣告行業(84/89):4A廣告代理公司與行業資質解讀

程序化廣告行業&#xff08;84/89&#xff09;&#xff1a;4A廣告代理公司與行業資質解讀 大家好&#xff01;在探索程序化廣告行業的道路上&#xff0c;每一次知識的分享都是我們共同進步的階梯。一直以來&#xff0c;我都希望能和大家攜手前行&#xff0c;深入了解這個充滿機…

deepin使用autokey添加微信快捷鍵一鍵顯隱ctrl+alt+w

打開deepin商店&#xff0c;搜索快捷鍵&#xff0c;找到autokey 快捷鍵管理&#xff0c;點擊安裝 點擊右鍵新建文件夾 點擊右鍵新建腳本 打開腳本并添加以下內容 import subprocess import time# ------------------ 配置項 ------------------ WM_CLASS "wechat…

文件內容課堂總結

Spark SQL是Spark用于結構化數據處理的模塊&#xff0c;前身是Shark。Shark基于Hive開發&#xff0c;雖提升了SQL-on-Hadoop效率&#xff0c;但對Hive依賴過多。2014年6月1日Shark項目停止開發&#xff0c;團隊將資源投入Spark SQL項目。Spark SQL具有諸多優點&#xff0c;如擺…

Zotero PDF Translate 翻譯插件使用OpenAI API配置教程

PDF Translate&#xff1a;提升 Zotero 內置 PDF 閱讀器的翻譯功能 “PDF Translate” 是一款為 Zotero 設計的插件&#xff0c;旨在方便用戶在 Zotero 內置的 PDF 閱讀器中進行劃詞或段落翻譯&#xff0c;輔助閱讀外文文獻。 一、 安裝插件 下載插件&#xff1a; 訪問 PDF T…

火山引擎旗下的產品

用戶問的是火山引擎旗下的產品&#xff0c;我需要詳細列出各個類別下的產品。首先&#xff0c;我得確認火山引擎有哪些主要業務領域&#xff0c;比如云計算、大數據、人工智能這些。然后&#xff0c;每個領域下具體有哪些產品呢&#xff1f;比如云計算方面可能有云服務器、容器…