IntelliJ IDEA 卡頓 CPU 使用率超過100%

先說結論,訂閱 Intellij IDEA 前先下載社群版,試著開個專案打打字(中英文都要),看看是否會卡頓,CPU 使用率是否會超過100%,會卡頓就不要訂閱。


IntelliJ IDEA 一打字就開始頓

最近負責的 Spring 專案中會包含 react 的程式碼,Eclipse 上找來找去都沒有免費合用的 plug-in 才能正確高亮提示,心一橫就訂閱了IntelliJ IDEA Ultimate 一年份。

之前開發 Android 都是用 IntelliJ IDEA 社群版,跑起來都很順,但這次的體驗卻非常差,運行起來超級頓,只是打字 CPU 的使用率就飆高到200%以上。

修改記憶體選項

工具列 > Help > Edit Custom VM Options…
# 檔案路徑在 /Applications/IntelliJ IDEA.app/Contents/bin/idea.vmoptions
# 預設值如下:
-Xms128m
-Xmx750m
-XX:ReservedCodeCacheSize=240m
預設值等於只允許 IntelliJ IDEA 使用750m 的記憶體,我筆電記憶體再大都沒有用,修改成最大可使用2g 的記憶體。
# 修改後的值如下:
-Xms1024m
-Xmx2048m
-XX:ReservedCodeCacheSize=1024m

關閉程式碼檢查

右下角會有一個人戴帽子的圖示,點擊後可以調整是否要檢查程式碼,都調整成 None。

降低 JIT Compiler 的 CPU 使用量

叫出 Activity Monitor 觀察 CPU 的使用量。

工具列 > Help > Edit Custom VM Options…
# 檔案路徑在 /Applications/IntelliJ IDEA.app/Contents/bin/idea.vmoptions
# 加入此列
-XX:TieredStopAtLevel=1
JIT Compiler 的 CPU 使用量有明顯降低,但 IntelliJ IDEA 只有微幅改善還是頓(因為還有其他問題占用 CPU)。

修改啟動的 JVM 版本

安裝 Plug-in:Choose Runtime,安裝後 Help > Find Action… 中搜尋”Choose Runtime” 可以開啟設定畫面,選擇你想要的 JVM 版本下載後重啟 Intellij IDEA。

沒有完全排除卡頓問題但已經可以接受

以下方法我都嘗試過的結果:
  • 降低 JIT Compiler CPU 使用率 // 有明顯改善
  • 修改記憶體 // 有些許改善
  • 關閉程式碼檢查 // 有些許改善
  • 修改 JVM // 根據選擇的 JVM 改善的幅度不同
  • 嘗試把不用的 Plug-in 關掉 // 沒改善
  • 嘗試不同版本 2020.1、2019.3、2019.2 // 沒改善
最終我修改的設定如下:
  • 降低 JIT Compiler CPU 使用率
  • 修改記憶體
  • 關閉程式碼檢查
  • 修改 JVM 改用 jbrsdk-8u202
  • Intellij IDEA 2019.3
CPU 使用率大概從原本200+%降到100+%,單純輸入英文沒太大不順的感覺,但輸入中文還是能感受輕微卡頓(我在想是不是輸入中文,Intellij IDEA 嘗試做 auto complete 還是建議輸入所造成)。

參考這篇 High CPU Usage while typing ( goes over 300%),問題依舊還沒有 close,花了錢訂閱了一個頓到不行的 IDE,只怪自己功課做得不夠多。

MySQL DATETIME 與 TIMESTAMP 的差別

 

DATETIME 與 TIMESTAMP 的差別

參考官方的說明

The DATETIME type is used when you need values that contain both date and time information. MySQL retrieves and displays DATETIME values in ‘YYYY-MM-DD HH:MM:SS’ format. The supported range is ‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’.

The TIMESTAMP data type has a range of ‘1970-01-01 00:00:01’ UTC to ‘2038-01-09 03:14:07’ UTC. It has varying properties, depending on the MySQL version and the SQL mode the server is running in.

MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such as DATETIME.)

簡單來說,兩個差別:
  • 支持的日期範圍不同:
    • DATETIME:1000-01-01 00:00:00 到 9999-12-31 23:59:59
    • TIMESTAMP:1970-01-01 00:00:01 UTC 到 2038-01-09 03:14:07 UTC
  • 儲存時對時區的處理:
    • DATETIME
      • 直接儲存不做任何轉換,你傳 2020-01-01 09:00 給 MySQL,MySQL 就當作是 2020-01-01 09:00 儲存。
      • 就算變更了 MySQL 時區,讀取出來也一樣是 2020-01-01 09:00。
    • TIMESTAMP
      • 儲存時會更根據 MySQL 時區先轉換成 UTC 時間,若 MySQL 時區是+8,你傳 2020-01-01 09:00 給 MySQL,MySQL 會轉成 2020-01-01 01:00 +00:00 儲存。
      • 讀取時會根據 MySQL 時區,將時間還原,以上例來說:
        • MySQL 時區還是+8,2020-01-01 01:00 +0000 會轉成 2020-01-01 09:00
        • 若讀取時 MySQL 時區改成+10,2020-01-01 01:00 +0000 會轉成 2020-01-01 11:00

要使用 DATETIME 還是 timestamp

如果你要儲存的日期範圍不在 1970-01-01 00:00:01 UTC 到 2038-01-09 03:14:07 UTC 之間,那就只有 DATETIME 可以選擇。但基本上西元2038年也不是太遠的未來了,所以現在應該都是優先使用 DATETIME。

PS:以上時間轉換只考慮到 MySQL 本身而已。若是你的程式跟 MySQL 串接,比如說 JDBC,JDBC 是會針對 MySQL 時區在儲存/讀取時作轉換的,請拆成兩個階段來思考比較好抓時區的問題。

Java 送出的時間與 MySQL 時間相差13個小時或差14個小時

MySQL 時間相差13或14個小時

Java 送出的時間有設定為台灣時區,但 MySQL 上看到的時間就是差13個小時,確認過 MySQL 主機時區是台灣的時區+8也沒有錯。
-- 在 MySQL 執行以下 SQL 指令,顯示 MySQL 時區以及 MySQL 主機時區
show variables like "%time_zone%";

-- 發現 system_time_zone 是 CST,代表 MySQL 主機時區是 CST
-- 發現 time_zone 是 SYSTEM,代表 MySQL 時區參考 MySQL 主機時區

發生原因在於 CST 可能是中國標準時間(China Standard Time)或是美國中部時間(Central Standard Time),造成 Java 認為 MySQL 時區是美國中部時間。

明確指定 MySQL 時區

MySQL 時區不要參考 MySQL 主機時區,明確指定 MySQL 時區為+8,讓 Java 明確知道要用+8的時區。

# 修改 my.cnf,在 [mysqld] 下增加:
default-time-zone = '+08:00'

# 需要重新啟動 MySQL
-- 重起後,重新在 MySQL 執行以下 SQL 指令,顯示 MySQL 時區以及 MySQL 主機時區
show variables like "%time_zone%";

-- system_time_zone 是 CST
-- time_zone 是 +08:00