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

相关文章
相关标签/搜索