JVM學習日記😄內存管理系列之探祕方法區

「這是我參與8月更文挑戰的第10天,活動詳情查看:8月更文挑戰java

引言

人要有點勇氣,勇於面對不丟人,本次文章出處來源於《深刻java虛擬機》,各位路見不平,要拔刀相助,每次我都拔不起刀,由於我以爲我這體格能幹過壞人嘛,今天忽然開悟了,我以爲不該該這麼懦弱,要有勇氣,要勇於直面生活中的一切,受傷的人要勇於面對,阻止施暴者繼續施暴,心裏的高尚纔是高尚的,我知道我如今作不到,我努力作到。markdown

方法區

我在《jvm的體系結構》一文中提到方法區,方法區的內部有一塊區域是常量池,是用來存儲一些咱們編譯時的符號引用的,由於編譯的時候,編譯器是找不到方法的具體位置的,故只能使用方法的符號去代替方法的位置,在解析時,將符號引用變爲實際引用,也就是方法實際所在的偏移位置。框架

既然都是內存確定就資源有限,確定有內存溢出的風險。jvm

常量池

java中,String::intern方法的是這樣定義的:若是字符串常量池中包含等於當前對象的字符串,則返回此String對象的引用,不然就會將該字符串的引用添加到常量池當中,並返回此對象的引用,那咱們能夠利用這一點,幹一件壞事(猥瑣),咱們能夠限制方法區的容量,而後不斷更新新的引用,不斷放到常量池中,就會溢出了。post

但須要說明的是jDK6之前,常量池是放在永久代的,但7之後的版本是挪在了堆上,因此測試的時候要注意JDK版本,否則測試是沒有意義的。測試

引伸部分

方法區的主要職責是存儲類型的相關信息的:類的類名、訪問描述符、訪問權限、常量池、方法描述符等等,那咱們就可使用代理幫咱們生成大量的類填滿咱們的方法區,可別以爲這個事離咱們很遠,實際上,咱們用的主流框架都須要用到動態代理這類技術,當咱們生成的類足夠多的時候,就須要足夠大的方法區。spa

JDK8之後,永久代永遠的退出了歷史的舞臺,元空間做爲新成員加入JDK,給使用者提供了一些參數來預防此類事件的發生:代理

  • -XX:MaxMetaspaceSize:設置元空間大小。默認-1
  • -XX:MetaspaceSize: 指定元空間初始大小。以字節爲單位,達到該值觸發垃圾收集進行類型卸載,同時收集器會動態調整,若是釋放了大量空間,會下降該值,反之提升但不會超過設置的元空間最大的大小。

題外話

被文字記錄下來的文化歷史,會永久的封存在記錄的史冊當中,而那些沒有記錄下來的,並隨着歷史遺蹟消失的古老文明就像那些遠遠望去看不到的浮塵,漂浮在不可知的永遠裏,漠視着人類的愚昧和無知。code

相關文章
相關標籤/搜索