龙空技术网

jvm——方法区

骑电动车的小黄 80

前言:

现时朋友们对“java的方法区”大约比较注意,小伙伴们都需要学习一些“java的方法区”的相关资讯。那么小编同时在网络上汇集了一些关于“java的方法区””的相关文章,希望姐妹们能喜欢,大家一起来了解一下吧!

概念

方法区翻译过来是Method Area与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载 的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。虽然jvm规范中把 方法区描述为堆的一个逻辑部分,但是它却有一个别名叫作“非堆”,目的是与Java堆区 分开来。

简单点来说它用于存储和类的结构相关的信息,比如类的成员变量、方法数据、成员方法和构造器方法代码部分,类的构造器,运行时常量池等。\

jdk1.7与jdk1.8的区别

方法区会在虚拟机启动时被创建,方法区逻辑上是堆的组成部分,但是不同虚拟机厂商的实现方式不一样。

就像oralce的HotSpot虚拟机在jdk1.8以前它的实现叫做永久代,这个永久代就是使用堆内存的一部分作为方法区,在1.8以后使用了了元空间实现,元空间就不是用的堆内存,它使用的是本地内存。

多了解了一下发现IBM的J9虚拟机,BEA的JRockit虚拟机,都没有把方法区放在堆中。

方法区内存溢出

方法区在申请内存时发现内存不足了,它也会让虚拟机抛一个 OutOfMemoryError 异常。

由于jdk1.8使用的是本地内存,不受jvm内存限制,一般jdk1.8方法区不会内存溢出,如果内存溢出了很大原因是本地内存不够了。

扩展小知识

在jdk1.8以前许多java程序员都习惯在HotSpot虚拟机上开发、部署程序,很多人都更愿意把方法区称呼为“永久代”,将两者混为一谈,本质上这两者不是等价的,仅仅是因为当时HotSpot虚拟机设计团队把收集器的分代设计扩展至方法区,这样使得 HotSpot 的垃圾收集器能够像管理Java堆一样管理这部分内存,省去专门为方法区编写内存管理代码的工作。但是对于其他虚拟机实现,譬如BEA JRockit、IBM J9等来说,是不存在永久代的概念的。

当Oracle收购BEA获得了 JRockit 的所有权后,准备把JRockit中的优秀功能,譬如Java Mission Control管理工具,移植到 HotSpot 虚拟机时,但因为两者对方法区实现的差异而面临诸多困难。考虑到HotSpot未来的发展,在JDK 6的 时候HotSpot开发团队就有放弃永久代,逐步改为采用本地内存(Native Memory)来实现方法区的计划了,到了JDK 7的HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移出,而到了 JDK 8,终于完全废弃了永久代的概念,改用与JRockit、J9一样在本地内存中实现的元空间(Meta space)来代替,把JDK 7中永久代还剩余的内容(主要是类型信息)全部移到元空间中。\

——————《深入理解Java虚拟机》

标签: #java的方法区