Java运行时数据区域解析(二)
Java虚拟机在Java程序执行的过程中会把其管理的内存分为若干个不同的数据区域。他们有着各自不同的特性。这些区域有的随着虚拟机进程的启动而一直存在,有的和用户线程同生共死。
五、方法区
- 方法区与堆一样,是各个线程共享的,用于存储被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
- 方法区是堆的一个逻辑部分,原则上如何实现方法区属于虚拟机实现细节,不受《Java虚拟机规范》管束,不要求统一。
- JDK7及之前使用永久代实现方法区,JDK8之后完全废弃了方法区e概念,改用在本地内存中实现的“元空间”来代替。
- 当方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。
六、运行时常量池
- 运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池表,用于存放编译期生成的各种字面量和符号引用,这部分在类加载后存放到方法区的运行时常量池中。
- 一般来说,除了符号引用,由它翻译而来的直接引用也会存储在运行时常量池中。
- 运行时常量池相比Class文件常量池的一个重要特征是具备动态性,Java语言并不要求常量只有在编译期才能产生,也就是说并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可以将新的常量放入池中。String类的intern方法就是利用这种特性编写的。
七、直接内存
- 直接内存并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。
- 在JDK1.4中新加入了NIO类(New Input/Output),引入了一种基于通道与缓冲区的IO方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了Java堆和Native堆之间来回复制数据。
- 显然,直接内存的分配不会受到Java堆内存大小的限制。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步