Java動態編譯優化——ZipFileIndex記憶體洩漏問題分析解決
一、前言:
前幾天解決了URLClassLoader記憶體洩漏的問題,但是解決問題就像剝洋蔥,剝去了外層,內層 問題又暴露出來了。當URLClassLoader記憶體洩漏解決, 需要解決的就是ZipFileIndex記憶體洩漏的問題了,而且這個問題折騰了我2天半的時間。
URLClassLoader問題解決:https://blog.csdn.net/moneyshi/article/details/81939477
二、ZipFileIndex問題發現
在執行動態編譯的時候,用VisualVM分析堆Dump,發現com.sun.tools.javac.file.ZipFileIndex$Entry 類和例項記憶體佔位元別高,僅居String之後,具體如下圖:
查詢資料,ZipFileIndex 是JavacFileManager裡面用到的一個處理檔案的類,在jdk1.7之後加入進來的,jdk1.9裡面被刪除了。
三、解決方案
1、設定useJavaUtilZip
為了解決ZipFileIndex記憶體洩漏的問題,查閱大量資料,其中有個解決方案就是編譯時設定useJavaUtilZip=true,具體程式碼如下:
System.setProperty("useJavaUtilZip", "true");
//使用編譯選項可以改變預設編譯行為。編譯選項是一個元素為String型別的Iterable集合
List<String> options = new ArrayList<>();
options.add("-encoding");
options.add("UTF-8");
options.add("-classpath");
// //獲取系統構建路徑
options.add(buildClassPath());
//不使用SharedNameTable (jdk1.7自帶的軟引用,會影響GC的回收,jdk1.9已經解決)
options.add("-XDuseUnsharedTable");
options.add("-XDuseJavaUtilZip");
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, options, null, jfiles);
但是實際上並沒什麼效果。ZipFileIndex記憶體佔比依然很高(不知道我是哪設定有問題)
2、升級JDK版本,由Java8升級到Java9
花了兩天時間,都沒找到什麼好的解決方案,於是我想到去Oracle/Java 的Bug列表去找我想要的答案,終於讓我找到了資料,說明了JDK升級到9之後,會刪除ZipFileIndex相關的類,加入java.nio.file來處理檔案編譯,具體如下:
Oracle/Java的bug列表:
https://www.oracle.com/search/results?Ntt=&Dy=1&Nty=1&cat=bugs&Ntk=S3
參考文獻:
https://bugs.java.com/view_bug.do?bug_id=8039262
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8061702
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8059976
升級Java 9 版本後,動態編譯 ZipFileIndex不在出現。 問題完美解決。
後續可能更新String 、 LinkedList 、 HashMap的記憶體洩漏問題解決方案。
相關文章
- Java動態編譯優化——URLClassLoader 記憶體洩漏問題解決Java編譯優化記憶體
- 解決記憶體洩漏(1)-ApacheKylin InternalThreadLocalMap洩漏問題分析記憶體Apachethread
- Java記憶體洩漏解決之道Java記憶體
- Handler記憶體洩漏分析及解決記憶體
- 記憶體洩漏問題分析之非託管資源洩漏記憶體
- ThreadLocal記憶體洩漏問題thread記憶體
- MAT工具定位分析Java堆記憶體洩漏問題方法Java記憶體
- Android效能優化篇之記憶體優化--記憶體洩漏Android優化記憶體
- 1.記憶體優化(一)記憶體洩漏記憶體優化
- 分析記憶體洩漏和goroutine洩漏記憶體Go
- 如何解決JVM OutOfMemoryError記憶體洩漏問題?JVMError記憶體
- Java記憶體洩漏Java記憶體
- redisson記憶體洩漏問題排查Redis記憶體
- JVM調優——Java動態編譯過程中的記憶體溢位問題JVMJava編譯記憶體溢位
- 分析ThreadLocal的弱引用與記憶體洩漏問題thread記憶體
- 翻譯 | 理解Java中的記憶體洩漏Java記憶體
- valgrind 記憶體洩漏分析記憶體
- Android 輕鬆解決記憶體洩漏Android記憶體
- 解決git記憶體洩露問題Git記憶體洩露
- PHP 記憶體洩漏分析定位PHP記憶體
- BufferedImage記憶體洩漏和溢位問題記憶體
- 關於PHP記憶體洩漏的問題PHP記憶體
- [譯] Swift 中的記憶體洩漏Swift記憶體
- 生產環境Java應用服務記憶體洩漏分析與解決Java記憶體
- 使用 Chrome Dev tools 分析應用的記憶體洩漏問題Chromedev記憶體
- Handler記憶體洩漏原因及解決方案記憶體
- 效能優化——記憶體洩漏(1)入門篇優化記憶體
- GCC8 編譯最佳化 BUG 導致的記憶體洩漏GC編譯記憶體
- linux程式之記憶體洩漏分析Linux記憶體
- 線上問題排查例項分析|關於Redis記憶體洩漏Redis記憶體
- 線上問題排查例項分析|關於 Redis 記憶體洩漏Redis記憶體
- 記憶體洩漏與排查流程——安卓效能優化記憶體安卓優化
- iOS效能優化 - 工具Instruments之Leaks記憶體洩漏iOS優化記憶體
- 解決Instruments檢測記憶體洩漏時真機無法定位的問題記憶體
- 納尼,Java 存在記憶體洩洩洩洩洩洩漏嗎?Java記憶體
- Java棧溢位|記憶體洩漏|記憶體溢位Java記憶體溢位
- [Java基礎]記憶體洩漏和記憶體溢位Java記憶體溢位
- 深入瞭解 JavaScript 記憶體洩漏JavaScript記憶體