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 异常。

相关文章
|
16天前
|
Java
jvm复习,深入理解java虚拟机一:运行时数据区域
这篇文章深入探讨了Java虚拟机的运行时数据区域,包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、元空间和运行时常量池,并讨论了它们的作用、特点以及与垃圾回收的关系。
49 19
jvm复习,深入理解java虚拟机一:运行时数据区域
|
7天前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
15 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
|
2天前
|
IDE Java 编译器
Java:如何确定编译和运行时类路径是否一致
类路径(Classpath)是JVM用于查找类文件的路径列表,对编译和运行Java程序至关重要。编译时通过`javac -classpath`指定,运行时通过`java -classpath`指定。IDE如Eclipse和IntelliJ IDEA也提供界面管理类路径。确保编译和运行时类路径一致,特别是外部库和项目内部类的路径设置。
|
7天前
|
Java
让星星⭐月亮告诉你,Java异常分类[Throwable(Error/Exception(RuntimeException/其他异常)) 检查时异常 非检查时异常]
本文深入解析了Java异常处理机制,重点介绍了`Throwable`类及其子类`Error`和`Exception`,并通过实例代码、流程图和表格详细解释了异常的分类、区别及处理方法,帮助读者掌握异常处理的关键技巧,提升程序的稳定性和健壮性。
22 1
|
12天前
|
Java 程序员
关于java异常
关于java异常
18 5
|
12天前
|
Java 程序员 编译器
Java中的异常类型
Java中的异常类型
19 3
|
1月前
|
Java 编译器 数据库连接
Java——异常
在 Java 中,程序执行过程中的不正常行为被称为异常。异常分为 Error 和 Exception。Error 表示系统级错误,而 Exception 则封装程序可能出现的问题。异常包括编译时异常和运行时异常(如数组越界)。异常可用于查找 bug 信息和作为方法内部的特殊返回值。处理异常的方式有默认处理和捕获异常,后者通过 try-catch 结构实现。此外,还可以自定义异常类来更灵活地处理特定情况。
32 9
Java——异常
|
12天前
|
存储 Java 编译器
【一步一步了解Java系列】:认识异常类
【一步一步了解Java系列】:认识异常类
19 2
|
15天前
|
Java 程序员 编译器
Java中的异常类型
Java中的异常类型
16 3
|
16天前
|
Java
Java异常捕捉处理和错误处理
Java异常捕捉处理和错误处理
17 1