运行时数据区域
Java虚拟机在执行Java程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。

方法区(重要)
- 方法区和Java堆一样,是各个线程的共享的区域,是系统分配的一个内存逻辑区域,它用于存放已被虚拟机加载的类信息(类的描述信息)、常量、静态变量、即时编译器编译后的代码等数据。在HotSpot里也叫“永生代”。但两者不能等同。如上图,字符串池在永生代中却在方法区外。
- 可以处于物理上不连续内存区域,但需要逻辑上连续。
- 又叫静态区,方法区包含所有的class和static变量以及常量。
- 该区域的垃圾收集比较少见,主要针对常量池的回收和类型的卸载。
- 方法区无法满足内存分配需求时,会抛出OutOfMemoryError异常。
运行时常量池
- 属于方法区的一部分。每个类私有
- 存放 Class 文件中的常量池(存放编译期生成的各种字面量和符号引用);翻译出来的直接引用;运行期间产生的新的常量(譬如 String 类的 intern() 方法)。
- 常量池无法申请到内存, 会抛出OutOfMemoryError异常。
直接内存

- 直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范定义中的内存区域。但这部分区域被频繁使用并可能引起OutOfMemoryError异常。
- NIO(New Input/Output)类中 ,可以使用 Native 函数库直接分配堆外内存,然后通过一个存储在 java 堆里面的 DirectByteBuffer 对象作为这块内存的引用进行操作,避免了在 Java 堆和 Native 堆中来回复制数据。
- 不受 Java 堆大小的限制,但受本机总内存的大小及处理器寻址空间的限制,会抛出 OutOfMemoryError异常。
参考:
付小德:JVM学习心得
胖胖:https://www.zhihu.com/question/22739143
Emanue:Java中几种常量池的区分
网友评论