方法区(Method Area)
- 方法区和Java堆一样,是各个线程共享的内存区域,主要用于存储已经被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
- 在《Java虚拟机规范》中把方法区描述为堆的一个逻辑部分,但方法区有一个别名:Non-Heap 。目的就是与Java堆分开。
- 在JDK8以前,大多数程序员都习惯使用HotSpot虚拟机上开发和部署程序,当时大家把“方法区”和“永久代”混为一谈。因为当时HotSpot虚拟机的设计团队使用永久代去实现了方法区,这样使得HotSpot的垃圾收集器能够像管理Java堆一样去管理方法区。省去了专门为方法区编写内存管理代码的工作。
- 对于其他的虚拟机来说,并不存在永久代的概念。
- 现在回头看,用永久代实现方法区的决定并不是一个好主意,这种设计会导致Java应用更容易遇到内存溢出的问题。所以在JDK6的时候,HotSpot放弃了永久代,逐步改为采用本地内存(Native Memory)来实现方法区。在JDK7时,将原本放在永久代的字符串常量池、静态变量等移至Java堆中。在JDK8中,完全废弃了永久代的概念,改用元空间来替代,并把JDK7中剩余留在永久代的内容(主要是类型信息)全部移到了元空间。
- 《Java虚拟机规范》对方法区的约束是非常宽松的,除了跟Java堆一样不需要连续的内存和可以选择固定大小或者可扩展之外,甚至还可以选择不实现垃圾收集。