之前根据平时的积累总结了篇博文“Java内存管理”,都是来自于平时的理解和积累,抽周末休息之余,翻阅了《深入理解Java虚拟机》第二章“Java内存区域与内存溢出异常”,将我的理解和总结分享给大家:
JVM的底层是用C++和少量的C完成编写的,所以在开章中作者很有诗意的写到“Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人想出来”。
当Java虚拟机在执行Java程序语言时会把分配给虚拟机的内存划分为以下几个区域:
堆(Heap)
方法区(Method Area)
虚拟机栈(VM Stack)
本地方法栈(Native Method Stack)
程序计数器(Program Counter Register)
五部分,其中堆和方法区是供所有线程共享的数据区,另外三部分是独立与线程相互隔离的数据区。
程序计数器(Program Counter Register):见名知意,计数器,针对程序的计数器,即当前线程在执行代码(字节码)时的行号指示器,字节码解释器负责调度当前线程的下一条所需要执行的字节码位置,如程序中的判断、循环、跳转、异常以及多线程切换睡眠后醒来需要执行的行号。由此可见为了保证多线程之间的有序调度,针对每个线程都分配了有一个独立的线程计数器,这样就能保证线程之间能相互协调工作,像这样的内存区域也就是针对线程独立运行的数据区,他们之间互不影响,就叫做“线程私有”内存。如果线程调度的是Java方法则计数器中记录的是正在执行的虚拟机字节码地址;如果执行的是Native方法此时计数器则为空。通俗的说程序计数器就是告知JVM中正在运行的线程下一步要执行的字节码。
虚拟机栈(VM Stack):VM Stack同Program Counter Register一样也是一块线程私有内存区域,线程私有内存有一个共同点就是他们的生命周期是与当前线程同步的,如果当前线程终结那么对应占用的内存空间也就立即释放。VM Stack内存是在Jvm执行Java方法时由不同栈帧(Stack Frame)所占有的,每运行到一个方法时就会分配一个栈帧,在栈帧内存放该方法的局部变量以及和该方法相关的信息,栈有一个特征就是有进有出,当一个方法被调用的时候那么就对应这个方法的栈帧入栈,方法执行完毕,那么该栈帧也就出栈,释放占用的内存资源。在编译期间可知的基本数据类型(boolean、byte、char、short、int、float、long、double)以及一些指向对象的引用就将存放在虚拟机栈中进行调度,这里所说的对象的引用并不是指的对象的本身,它指的是指向对象的一个地址引用指针,或者是指向代表对象的句柄。所以如果当一个线程如果需要申请的栈内存空间超过虚拟机预先设定的栈空间那么就会抛出StackOverflowError异常;还有一种情况是虚拟机栈可以自己根据实际情况动态扩展,如果实际情况需要扩展更大的空间满足线程运行需要,但是此时无法申请到内存空间时就会抛出OutOfMemoryError异常。
本地方法栈(Native Method Stack):它跟VM Stack栈类似,同样也是一块线程私有内存,唯一不同的是他服务的对象不是Java方法,而是Native方法,他也会抛出StackOverflowError和OutOfMemoryError异常。
堆(Heap):这是占用JVM大量内存的一块区域,这块区域不是线程私有内存,而是所有线程共享的,在虚拟机启动时根据事先的虚拟机设定就已经分配了该空间,该区域存放的是大量的实例对象或数组。至于存放该区域的空间对象的生命周期和空间利用都由JVM的垃圾收集器统一管理,如果该区域不能满足新的实例对象所需要的存放空间那么就会抛出OutOfMemoryError异常。
方法区(Method Area):与堆一样也是所有线程可以共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态常量、即时编译器编译后的代码 等数据。当他不能满足新的内存需求分配时他会抛出OutOfMemoryError异常。这里还有一个概念就是运行时常量池(Runtime Constant Pool),他是方法区的一部分,是方法区的一个子集,用于存放编译期生成的各种字面量和符号引用,类一旦被加载后这部分内容就被置入到了常量池中。你会发现也正是类信息、常量、静态常量和各种字面量和符号引用组成了class文件,在运行期间可以通过String类得intern()方法将新的数据置入常量池,所以我们可以理解class文件的所有信息都被放入到了方法区(当然包括常量池),常量池也会受到内存的限制,他不能满足新的内存需求分配时他会抛出OutOfMemoryError异常。
分享到:
相关推荐
Java内存区域与内存溢出异常.pdf
Java内存区域是Java虚拟机(JVM)管理内存的核心组成部分,它们主要分为以下几个部分: 1. **程序计数器(Program...开发者应当关注内存分配、垃圾收集策略以及对象访问方式,以提高程序效率并避免内存溢出异常。
这是自己读《深入理解Java虚拟机》时候用XMind建立的思维导图,目的是为了能够帮助自己整理、梳理相关的知识以及方便自己日后的回顾,帮助自己建立起关于JVM的知识体系,里边也有一些对相关内容的补充,通过备注的...
JAVA内存溢出问题总结 JAVA 内存溢出问题是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用的内存大于虚拟机能提供的最大内存。内存溢出问题可以从容器和程序类两个方面进行排查,容器问题...
Java内存区域与内存溢出异常详解 Java内存区域可以分为程序计数器、虚拟机栈、本地方法栈、堆、方法区五个部分。每个部分都有其特定的作用和生命周期。 1. 程序计数器(Program Counter Register):是当前线程所...
Java内存机制是Java虚拟机(JVM)的关键组成部分,它管理着程序运行时的数据存储。在Java中,内存主要分为以下几个区域: ...正确理解和运用Java内存机制以及异常处理机制对于开发健壮、高效的Java应用程序至关重要。
Java内存溢出问题,全称为Java OutOfMemoryError,是Java开发者经常遇到的运行时异常。内存溢出通常发生在程序运行过程中,系统无法为运行的应用程序分配足够的内存资源,导致程序无法正常执行。理解并解决Java内存...
Java内存溢出问题通常指的是程序在试图分配内存时,无法找到足够的连续内存空间而抛出的异常。在Java中,内存分为几个区域:堆(Heap)、栈(Stack)、方法区(Method Area,Java 8后被元空间取代)以及程序计数器和...
Java堆是Java虚拟机中最大的一块内存区域,用于存储对象实例。当程序创建新的对象并分配给堆时,如果堆空间不足,就会抛出`OutOfMemoryError: Java heap space`异常。Java应用程序可以通过设置JVM的启动参数来控制堆...
Java内存溢出问题通常指的是Java应用程序在运行过程中由于内存分配不当或使用过度导致JVM无法分配更多的内存,从而抛出`java.lang.OutOfMemoryError`异常。本文将深入探讨Java内存溢出的不同类型及其解决方案。 1. ...
在Java虚拟机(JVM)中,不同的内存区域负责不同的功能,并且各自可能会出现特定类型的内存溢出异常。通过本实验,旨在深入理解JVM内存管理机制以及各种内存区域的特点,并通过具体的编程实践来触发并分析这些异常,...
在 JVM 中,如果 98%的时间是用于 GC 且可用的 Heap size 不足 2%的时候将抛出内存溢出异常信息。Heap Size 最大不要超过可用物理内存的 80%,一般的要将 Xmx 和 Xms 设置相同避免每次 GC 后都要调整虚拟机堆的...
#### 一、Java内存区域与内存溢出异常 Java虚拟机(JVM)在运行过程中会管理多种不同的内存区域,这些区域各自承担着特定的任务,并且每种区域都有可能发生内存溢出异常。 ##### 1.1 程序计数器(Program Counter ...
10. **日志和异常处理**:当发生内存溢出时,JVM会生成堆转储文件(hprof),通过分析这些文件可以找出问题原因。同时,良好的异常处理和日志记录可以帮助追踪问题。 11. **监控与调优**:使用JMX(Java Management...
Java编程常见内存溢出异常与代码示例 在Java编程中,内存溢出异常是非常常见的错误之一,了解内存溢出异常的原因和解决方法是非常重要的。本文将详细介绍Java编程中常见的内存溢出异常和代码示例,帮助读者更好地...
不同的内存区域可能出现不同的内存溢出异常,如`OutOfMemoryError`。 1. `java.lang.OutOfMemoryError`: 这是最常见的内存溢出异常,可能由于以下几个原因: - JVM内存设置过小:如果分配给JVM的内存不足,当程序...
#### 二、Java内存模型与内存区域 Java虚拟机(JVM)管理着多种不同类型的内存区域,包括堆内存(Heap Memory)、方法区(Method Area)、永久代(Permanent Generation Space)等。不同的内存区域有着不同的作用和特点: ...
每一个Java应用程序启动时都会创建一个独立的Java虚拟机(JVM)实例,每个JVM实例都会有自己的Java堆内存区域。 - **内存分配与回收**:当我们在代码中创建一个新的对象时,JVM会在堆内存中为其分配一块内存。当...
Java内存管理和内存问题,特别是内存泄露与内存溢出,是Java开发者必须面对的重要主题。本文主要探讨了Java内存溢出的检查方法和工具,以及内存泄露的基本原理。 首先,当Java应用程序抛出`java.lang....
Java内存管理是Java虚拟机(JVM)的关键组成部分,它主要负责对象的创建、分配、...总的来说,理解Java内存管理与内存溢出异常对于优化应用性能、防止系统崩溃至关重要。开发者应关注内存使用,确保程序高效且健壮。