Java内存区域与内存溢出异常 - 运行时数据区

简介: 【8月更文挑战第2天】Java运行时数据区包括:1) 程序计数器:记录线程执行字节码的行号,线程私有;2) Java虚拟机栈:描述方法执行的内存模型,线程私有,深度过大抛出`StackOverflowError`;3) 本地方法栈:服务于Native方法,线程私有;4) Java堆:所有线程共享,对象实例在此分配内存;5) 方法区:存储类信息、常量等数据;6) 运行时常量池:方法区的一部分,存放字面量和符号引用。不当使用如无限创建对象或过度递归调用会导致各种内存溢出错误。

Java 运行时数据区


Java 运行时数据区主要包括以下几个部分:


  1. 程序计数器(Program Counter Register)
  • 是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。
  • 每个线程都有一个独立的程序计数器,线程私有,此区域不会出现内存溢出异常。
  1. Java 虚拟机栈(Java Virtual Machine Stacks)
  • 描述的是 Java 方法执行的内存模型。
  • 每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
  • 线程私有,如果线程请求的栈深度大于虚拟机所允许的深度,将抛出 StackOverflowError 异常;如果虚拟机栈可以动态扩展,但扩展时无法申请到足够的内存,会抛出 OutOfMemoryError 异常。
  1. 本地方法栈(Native Method Stacks)
  • 与虚拟机栈的作用类似,只不过本地方法栈为虚拟机使用到的 Native 方法服务。
  • 同样线程私有,也可能抛出 StackOverflowErrorOutOfMemoryError 异常。
  1. Java 堆(Java Heap)
  • 是被所有线程共享的一块内存区域,几乎所有的对象实例以及数组都在这里分配内存。
  • 如果堆中没有足够的内存完成实例分配,并且堆也无法再扩展时,将会抛出 OutOfMemoryError 异常。
  1. 方法区(Method Area)
  • 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
  • 当方法区无法满足内存分配需求时,会抛出 OutOfMemoryError 异常。
  1. 运行时常量池(Runtime Constant Pool)
  • 是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。
  • 当常量池无法再申请到内存时会抛出 OutOfMemoryError 异常。


例如,如果在一个 Java 程序中,不断创建大量的对象并且不进行垃圾回收,最终可能导致堆内存溢出:


public class HeapOverflowExample {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        while (true) {
            list.add(new Object());
        }
    }
}


当运行上述代码时,很快就会出现 OutOfMemoryError 异常。


再比如,如果一个方法递归调用次数过多,可能会导致栈溢出:


public class StackOverflowExample {
    public static void main(String[] args) {
        recursiveMethod();
    }
    public static void recursiveMethod() {
        recursiveMethod();
    }
}


运行这段代码,会抛出 StackOverflowError 异常。

相关文章
|
3天前
|
算法 安全 Java
Java内存管理:深入理解垃圾收集器
在Java的世界里,内存管理是一块基石,它支撑着应用程序的稳定运行。本文将带你走进Java的垃圾收集器(GC),探索它是如何默默守护着我们的内存安全。我们将从垃圾收集的基本概念出发,逐步深入到不同垃圾收集器的工作机制,并通过实例分析它们在实际应用中的表现。文章不仅旨在提升你对Java内存管理的认识,更希望你能通过这些知识优化你的代码,让程序运行更加高效。
20 3
|
1天前
|
安全 Java API
【性能与安全的双重飞跃】JDK 22外部函数与内存API:JNI的继任者,引领Java新潮流!
【9月更文挑战第7天】JDK 22外部函数与内存API的发布,标志着Java在性能与安全性方面实现了双重飞跃。作为JNI的继任者,这一新特性不仅简化了Java与本地代码的交互过程,还提升了程序的性能和安全性。我们有理由相信,在外部函数与内存API的引领下,Java将开启一个全新的编程时代,为开发者们带来更加高效、更加安全的编程体验。让我们共同期待Java在未来的辉煌成就!
20 11
|
2天前
|
安全 Java API
【本地与Java无缝对接】JDK 22外部函数和内存API:JNI终结者,性能与安全双提升!
【9月更文挑战第6天】JDK 22的外部函数和内存API无疑是Java编程语言发展史上的一个重要里程碑。它不仅解决了JNI的诸多局限和挑战,还为Java与本地代码的互操作提供了更加高效、安全和简洁的解决方案。随着FFM API的逐渐成熟和完善,我们有理由相信,Java将在更多领域展现出其强大的生命力和竞争力。让我们共同期待Java编程新纪元的到来!
21 11
|
5天前
|
Java C++
Java内存区域于内存溢出异常
这篇文章详细解释了Java虚拟机的内存区域划分、各区域的作用以及可能遇到的内存溢出异常情况。
14 0
|
20天前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
|
2月前
|
存储 分布式计算 Hadoop
HadoopCPU、内存、存储限制
【7月更文挑战第13天】
162 14
|
10天前
|
存储 监控 Docker
如何限制docker使用的cpu,内存,存储
如何限制docker使用的cpu,内存,存储
|
2月前
|
存储 固态存储 芯片
计算机中内存与存储
【7月更文挑战第28天】
31 1
|
2月前
|
存储 弹性计算 程序员
新手程序员如何阿里云服务器配置?新人开发者CPU内存带宽存储怎么选?
对于新手开发者、个人或学生选择阿里云服务器,推荐ECS经济型e实例(ecs.e-c1m1.large),适用于小型网站或轻量应用。配置2核2G内存、3M固定带宽、40G ESSD系统盘,仅99元/年且续费同价。
|
26天前
|
存储 编译器 C语言
数据在内存中的存储
数据在内存中的存储
下一篇
DDNS