JVM运行时数据区(方法区)(3)

12 篇文章 0 订阅

6.方法区

6.1 方法区的基本理解:
方法区,是一个被线程共享的内存区域。其中主要存储加载的类字节码、 class/method/field 等元数据、static final 常量、static 变量、即时编译器编译后的代码等数据。另外,方法区包含了一个特殊的区域“运行时常量池”。

Java 虚拟机规范中明确说明:”尽管所有的方法区在逻辑上是属于堆的一部分,但对于 HotSpotJVM 而言,方法区还有一个别名叫做 Non-Heap(非堆),目的就是 要和堆分开.

所以,方法区看做是一块独立于 java 堆的内存空间.
在这里插入图片描述
方法区在 JVM 启动时被创建,并且它的实际的物理内存空间中和 Java 堆区一样都可以 是不连续的.

方法区的大小,跟堆空间一样,可以选择固定大小或者可扩展.

方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出, 虚拟机同样会抛出内存溢出的错误

概述:(方法区也是一块内存空间,逻辑上属于堆,为了区分,称为元空间(jdk8以后),主要用于存储类的信息,在jvm启动时创建,大小可以分配,如果加载的类太多,也会报内存溢出的错误,是线程共享的)

public class Demo1 {

    public static void main(String[] args) {
        String temp = "world";    //字符串是常量
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            String str = temp + temp;
            temp = str;
            str.intern();//将字符串存储到字符串常量池中 } }
        }
    }
}

运行结果:
在这里插入图片描述

方法区,栈,堆的交互关系:

在这里插入图片描述
6.2 方法区大小设置:

Java 方法区的大小不必是固定的,JVM 可以根据应用的需要动态调整.

 元数据区大小可以使用参数-XX:MetaspaceSize 和 -XX:MaxMataspaceSize 指定,替代上述原有的两个参数.

 默认值依赖于平台,windows 下,-XXMetaspaceSize是21MB,

 -XX:MaxMetaspaceSize 的值是-1,没有限制.

 这个-XX:MetaspaceSize 初始值是 21M 也称为高水位线,一旦触及就会触发 Full GC.

 因此为了减少 FullGC 那么这个-XX:MetaspaceSize 可以设置一个较高的值.

概述:(方法区大小可以通过-XX:MetaspaceSize设置:
方法区在Windows中默认的大小是21Mb ,如果达到21Mb会触发FULL GC,因此可以将其值设置的大一些,会减少FUll GC的触发.)

6.3 方法区的内部结构:

在这里插入图片描述
方法区它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编 译后的代码缓存,运行常量池等。

通过反编译字节码文件查看.

反编译字节码文件,并输出值文本文件中,便于查看。参数 -p 确保能查看 private 权限类型的字段或方法

javap -v -p   文件名.class > test.txt

右击文件,选择 Open in Terminal
在这里插入图片描述

然后输入指令:
在这里插入图片描述

会生成一个txt文件:
在这里插入图片描述

打开后会看到编译后这个类的信息.

6.4 方法区的垃圾回收:

1.有些人认为方法区(如 Hotspot 虚拟机中的元空间或者永久代)是没有垃圾 收集行为的,其实不然。《Java 虚拟机规范》对方法区的约束是非常宽松的, 提到过可以不要求虚拟机在方法区中实现垃圾收集。

2.一般来说这个区域的回收效果比较难令人满意,尤其是类型的卸载,条件相当苛刻。但是这部分区域的回收有时又确实是必要的。

方法区的垃圾收集主要回收两部分内容:运行时常量池中废弃的常量和不再使用的类型。

下面也称作类卸载

判定一个常量是否“废弃”还是相对简单,而要判定一个类型是否属于“不再被 使用的类”的条件就比较苛刻了。需要同时满足下面三个条件:

1.该类所有的实例都已经被回收,也就是 Java 堆中不存在该类及其任何派生子类的实例。

2.加载该类的类加载器已经被回收,这个条件除非是经过精心设计的可替换类加 载器的场景,如 OSGi、JSP 的重加载等,否则通常是很难达成的。

3.该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

概述:(方法区中主要回收运行时常量池,类的信息
类的信息卸载(回收)条件是比较苛刻的,满足的3个条件:
1.该类以及子类的对象没有被使用,
2.该类的类加载器被卸载,
3.该类的Class对象也没有被引用)

到此,运行时数据区的基本概念已经结束了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值