方法区与Java堆一样,是各个线程共享的内存区域,他在与存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,虽然Java虚拟机规范把方法区描述为堆得一个逻辑部分,但是他却有一个别名Non-heap(非堆),目的是与Java堆区分开来。
对于习惯在Hotspot虚拟机上开发和部署程序的开发者来说,很多人愿意把方法区称为永久代(Permanent generation),本质上两者并不等价,仅仅是因为Hotspot虚拟机的设计团队选择把gc分代收集扩展中方法区,,或者说使用永久代来实现方法区而已。对于其他虚拟机来说不存在永久代的概念的,即使是Hotspot虚拟机本身,根据官方发布的路线图信息,现在也有放弃永久代并搬家至nativememory来实现方法区的规划了。
Java虚拟机规范对这个区域的限制非常宽松,除了和Java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。相对而言,垃圾收集行为在方法区是比较少出现的,但是并非数据进入方法区就如进入永久代的名字一样永久存在了。这个区域的内存回收主要目标是针对常量池的回收和对类型的卸载,一般 来说这个区域的回收成绩比较难以令人满意,尤其是类型的卸载,条件相当苛刻,但是这部分区域的回收确实是必要的。
根据Java虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出outofmemorryerror异常。