网站首页 > java教程 正文
前文《Java面试必考问题:JVM内存区域如何划分? 》介绍了Java虚拟机内存的划分,主要包括5个部分:方法区、堆、虚拟机栈、本地方法栈以及程序计数器,其中方法区和堆是各线程共享的存储区域,关于堆的内存管理机制在前面的文章《Java面试必考问题:Java堆内存管理机制 》中已经介绍过,本文重点介绍一下Java方法区。
方法区概述
我们还是以HotSpot VM来介绍方法区(Method Area)是如何实现的,内存又是如何管理的。对于HotSpot VM而言,方法区还有一个别名叫做Non-Heap(非堆),意思就是要和堆(Heap)分开。方法区可以看作是一块独立于Java堆的内存空间。
创建一个新的对象,对象引用在虚拟机栈中,对象实例数据在堆中,实例数据中还包括对象类型数据的指针,对象类型数据则存放在方法区。
方法区的大小决定了系统可以保存多少个类,和堆一样,方法区也可能会抛出内存溢出错误。如果系统定义了太多的类,就有可能导致方法区溢出。在Jdk1.7版本及以前,会抛 java.lang.OutofMemoryError : PermGen space;在Jdk1.8及以后,会抛 java.lang.OutofMemoryError : Metaspace。
之所以不同Jdk版本抛出的异常有区别,是因为HotSpot的变化。《Java界大名鼎鼎的HotSpot虚拟机的演进之路 》中曾介绍过在Jdk1.8版本中,HotSpot VM用元空间取代了之前的永久代来实现方法区。元空间的本质和永久代类似,都是对JVM规范中方法区的实现,两者的主要区别在于:元空间不在虚拟机设置的内存中,而是使用本地内存。
方法区的内存结构
方法区保存的信息包括:
(1)类型信息:包括了JVM加载类型(类class、接口interface、枚举enum、注解annotation)的完整有效名称(包名+类名)、其直接父类的完整有效名称、类型的修饰符、其直接继承的接口列表。
(2)域(成员变量)信息:类型的所有成员变量的相关信息以及成员变量的声明顺序。
(3)方法信息:包括了类型的成员方法的名称、返回类型、参数列表、修饰符、字节码、操作数栈、局部变量表、异常表等。
(4)静态变量:non-final的静态类变量和全局常量。区别在于全局常量在编译器给指定值,静态类变量在加载时准备阶段赋初值,初始化阶段再给指定值。
(5)JIT代码缓存:即时编译产生的代码缓存,将热点代码编译成与本地平台相关的机器码,并保存到内存。
(6)运行时常量池:各种字面量和对类型、域和方法的符号引用。
方法区的大小和GC
以Jdk1.8版本的HotSpot为例,元数据区的大小可以使用参数 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 指定。默认的 XX:MetaspaceSize 值为21MB,-XX:MaxMetaspaceSize 默认为-1,即没有限制。
XX:MetaspaceSize 是元空间初始大小,一旦触及这个水位线,会触发垃圾回收(GC)并卸载没用的类。如果元空间初始大小设置过低,那么会频繁触发GC,为避免如此,一般将 XX:MetaspaceSize 设置为相对较高的值。
-XX:MaxMetaspaceSize 是元空间最大可分配大小,默认情况下,元空间最大的大小是系统内存的大小,元空间一直扩大,虚拟机可能会消耗完所有的可用系统内存。
方法区GC主要回收的内存包括:
1、常量池中没被引用的常量:字面量和符号引用。
2、不再使用的类型(class、interface等)。
对类型进行回收不是必要的,HotSpot虚拟机提供了-Xnoclassgc 参数进行控制,可以关闭虚拟机对 class 的垃圾回收功能。
我会持续更新关于物联网、云原生以及数字科技方面的文章,用简单的语言描述复杂的技术,也会偶尔发表一下对IT产业的看法,欢迎大家关注,谢谢。
- 上一篇: Java异常处理和最佳实践(含案例分析)
- 下一篇: Java从入门到精通到全栈
猜你喜欢
- 2024-12-11 Java多线程系列(四):4种常用Java线程锁的特点...
- 2024-12-11 concurrenthashmap在1.7和1.8中的区别
- 2024-12-11 Java从入门到精通到全栈
- 2024-12-11 Java异常处理和最佳实践(含案例分析)
- 2024-12-11 时代变了,对比完Rust,发现Java差一大截!
- 2024-12-11 高并发编程系列:4大Java线程锁全面详解
- 2024-12-11 AMD 锐龙7 2700/锐龙5 2600评测:搭配这个黑科技,游戏变得更快
- 2024-12-11 用云存储30分钟快速搭建APP,你信吗?
- 2024-12-11 Java当中的一些奇技淫巧
- 2024-12-11 Java 注解(Annotation)
你 发表评论:
欢迎- 最近发表
-
- 多种负载均衡算法及其Java代码实现
- 输入www.baidu.com背后经历了啥?说清楚这个,已经超过90%的人了
- 优化MySQL:为什么你应该用 UNSIGNED INT 存储IP地址
- 实模式下CPU如何获取数据及指令(实模式寻址方式)
- java基础都在这了,小主们拿去吧(java基础是指什么)
- 盘点爬虫语言为何选择Python而不是Java
- 搭载Dubbo+Zookeeper踩了这么多坑,我终于决定写下这篇
- 网络协议之TCP/IP协议(面试必考内容) - javaEE初阶 - 细节狂魔
- 深夜报警!10亿次请求暴击,如何用Redis找出最热IP?
- VPN技术(IPsec/L2TP/SSLVPN/PPTP)学习笔记
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)