共計 2738 個字符,預計需要花費 7 分鐘才能閱讀完成。
本文丸趣 TV 小編為大家詳細介紹“Tomcat 內存配置的方法是什么”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Tomcat 內存配置的方法是什么”文章能幫助大家解決疑惑,下面跟著丸趣 TV 小編的思路慢慢深入,一起來學習新知識吧。
1. 背景
本文特別備注只介紹基于 HotSpot VM 虛擬機, 并且基于 JDK1.7 的內存分配情況, 有關 GC 的說法也是基于 CMS 的 concurrent collection(而非 G1), 防止大牛拍磚.
目前主流的 JVM 就是 HotSpot VM(其次還有 J9 VM,Zing VM), 目前各類博客文章也大多基于 JDK1.7 以前的版本進行闡述的.
(注: 因為不同的虛擬機實現, 不同的 JDK, 內存的分布都不一樣, 也就是說下面文章中提到的內存結構都只是邏輯結構, 并不是內存的物理結構)
2. 內存總體結構
如果只是為了解決問題, 不想了解其中緣由的請跳過本章節
本文介紹的是垃圾回收的內存區域的結構 (簡稱 GC 堆, 不包括程序計數器, 棧, 本地方法棧),引用一個大牛的說法《一個 java 對象的這一輩子》
我是一個普通的 Java 對象,我出生在 Eden 區,在 Eden 區我還看到和我長的很像的小兄弟 (其他 java 對象),我們在 Eden 區中玩了挺長時間。有一天 Eden 區中的人實在是太多了 (會觸發 Young GC, 每次 GC 加一歲)),我就被迫去了 Survivor 區的“From”區,自從去了 Survivor 區,我就開始漂了,有時候在 Survivor 的“From”區,有時候在 Survivor 的“To”區,居無定所 (每次 Young GC 都需要 Survivor 區中的 from 區和 to 區 對調)。直到我 18 歲的時候 (進行了 18 次 Young GC),爸爸說我成人了,該去社會上闖闖了。于是我就去了年老代那邊,年老代里,人很多,并且年齡都挺大的,我在這里也認識了很多人。在年老代里,我生活了 20 年,然后被回收 (Old GC)。
解釋一下, 首先內存總體分為年輕代 (young), 老年代 (old),*** 代 (permanent), 如下圖
年輕代:(針對年輕代的垃圾回收我們簡稱 Young GC)
年輕代分為 eden 區,survivor 區
1.eden 區, 是 new Object(), 對象誕生的地方
2.survivor 區是經過垃圾回收后的仍存活的對象存儲區域,survivor 區中又分為 from 區和 to 區
2.1.from 區: 經過 GC 回收,eden 區和 to 區仍存活的對象會存放在 from 區
2.2.to 區: 經過 GC 回收,eden 區和 from 區仍存活的對象會轉移到 to 區
2.3. 正因為 2.1 和 2.2 的操作, 所以 from 區和 to 區中的存活對象來回轉移, 并且始終有一個區是空的
老年代:(針對老年代的垃圾回收簡稱 Old GC)
經過 18 次 Young GC 后年輕代中仍存活的對象, 會從年輕代中轉移到老年代
老年代滿了之后, 會觸發 Old GC, 仍存活的對象繼續保留在老年代中, 直到經過 20 次 Old GC 進行回收
*** 代:(針對年輕代 + 老年代 +*** 代的回收簡稱 Full GC)
是 HotSpot VM 針對 Java 方法區的一個實現, 通常存儲類信息、常量池、靜態變量、JIT 編譯后的代碼等數據 (簡單理解成編譯代碼的存儲區域, 即可以理解成: 我們的 java 項目運行時, 加載的類文件越多, 則需要的 *** 代內存空間越大)
(注: 據說 *** 代是 Hotspot 虛擬機特有的概念,別的 JVM 都沒有這個東西,在 Java 8 中,*** 代被徹底移除,取而代之的是另一塊與堆不相連的本地內存 mdash; mdash; 元空間)
3. 通常內存問題解釋
常見問題一 java.lang.OutOfMemoryError: Java heap space —-JVM Heap(堆) 溢出
原因: 項目運行階段,new 的對象過多, 撐滿了配置的 *** 內存, 會出現該錯誤
解決方法: 手動設置 Xms ,Xmx 的大小.
常見問題二 java.lang.OutOfMemoryError: PermGen space —-PermGen space (*** 代) 溢出
原因: 開發的項目 Java 文件比較多的時候, 會出現該錯誤 (即項目很大, 被 JVM 加載的文件很多)
解決方法: 手動設置 MaxPermSize 大小.
常見問題三 java.lang.StackOverflowError —- 棧溢出
原因: 通常都是某個代碼邏輯遞歸層次太多導致的,
解決方法: 修改遞歸代碼, 控制遞歸層數
4. 內存分配方法 (建議, 非 ***)
本文只介紹常用的一些配置參數, 通常情況下 *** 代不算堆內存 (單獨占用另一塊內存),新生代占年老代的 1 /2,即占整個堆內存的 1 /3,按照這個原則我們給出一個配置例子。
比如服務器可以提供 1G 的內存以供項目使用,依據上圖我們給出如下配置。
運行模式:
-server 服務器模式, 多 CPU 時, 性能更佳
新生代與老年代:(通常不單獨配置新生代與老年代, 所以直接配置整個內存堆大小即可)
-Xms384m 內存堆初始的內存空間
-Xmx768m 內存堆 *** 內存空間
*** 代:(新生代, 老年代配置剩余的內存留給 *** 代)— 注意 jdk1.8 已移除
-XX:PermSize=128m *** 代初始化大小
-XX:MaxPermSize=256m *** 代 *** 的內存空間 (默認為 64m)
4. 不同環境下的 Tomcat 內存配置方法
前面已經進行各類內存問題的詳解以及配置參數的簡要介紹, 下面我們介紹一下各種環境下的具體配置方法.
1. 使用命令行啟動的 tomcat:
修改 TOMCAT_HOME/bin/catalina.sh(windows 中是 catalina.bat), 在文件上方添加如下語句
JAVA_OPTS= -server -Xms384m -Xmx768m -XX:PermSize=128m -XX:MaxPermSize=256m
2. 如果 tomcat 注冊成了 windows 服務, 使用 tomcat 目錄中的 /bin/tomcat8w.exe 修改就可以了. 如下圖
3. 如果是使用 myeclipse 開發中, 啟動 tomcat, 上述的修改就不起作用了, 可進行如下設置:
Myeclipse- preferences- myeclipse- servers- tomcat- tomcat times;. times;- JDK 面板中的 Optional Java VM arguments 中添加如下內容:
-server -Xms384m -Xmx768m -XX:PermSize=128m -XX:MaxPermSize=256m
讀到這里,這篇“Tomcat 內存配置的方法是什么”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注丸趣 TV 行業資訊頻道。