不同于C,C++程序,Java程序的内存管理工作由Java虚拟机(JVM)接管,这减低了java程序员的负担,但如果出现内存泄露与溢出问题如报OutOfMemory,StackOverFlow异常错误时,如果不了解JVM虚拟机的内存管理细节,往往很难快速定位错误。

  JVM在运行时会把其所管理的内存分为几个不同的数据区域,分别为:程序计数器,虚拟机栈,本地方法栈,堆,方法区等。这些区域存放的数据不同,功能也不同。

  JVM管理的内存包含以下几个运行时数据区:

1.程序计数器

  程序计数器是一块较小的内存空间,可将其视为当前线程所执行字节码的行号指示器。为了线程切换后能恢复到正确执行的位置,每条线程都需要有单独的程序计数器,使各线程之间互不干扰,独立存储。因此该区域是线程私有区。

  值得一提的是,该区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError异常的区域。

2.Java虚拟机栈

  Java虚拟机栈也是线程私有的。虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行的同时会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每个方法从调用直至执行完成的过程,就是一个栈帧在虚拟机栈中入栈出栈的过程。

  局部变量表存放了编译期可知的各种基本数据类型(boolean,byte,char,int,short,float,double,long),对象引用)和returnAddress(指向一条字节码指令的地址)类型。局部变量表所需内存空间在编译期间完成分配。

  在Java虚拟机规范中,该区域规定了两种异常状况:若果线程请求的栈深度大于虚拟机允许的深度,将抛出StackOverFlow异常;如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfemory异常。

3.本地方法栈

  本地方法栈与虚拟机栈发挥相似你的作用,本地方法栈为虚拟机用到的native方法服务。有的虚拟机直接将本地方法栈与虚拟机栈合并。本地方法栈也会抛出StackOverFlow与OutOfMemoryError异常。

4.Java堆

  Java堆是我们最熟悉的一块区域,它是Java虚拟机所管理的最大的一块内存。Java堆是由所有线程共享的一块内存区域,在虚拟机启动时创建。该内存区的唯一目的就是存放对象实例,几乎所有的对象实例都在Java堆分配内存。Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。在实际中,Java堆是可扩展的,一般有参数:-Xmx(堆最大值)    -Xms(堆最小值)控制。如果在堆中没有内存完成实例分配,且堆也无法再扩展时,会抛出OutOfMemoryError异常。

5.方法区

  方法区也是各个线程共享的内存区,它用于存储被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。当方法区无法满足内存分配的需求时,将抛出OutOfMemoryError异常。

6.运行时常量池

  运行时常量池是方法区的一部分。Class文件中除了有类的版本,字段,方法,接口等信息外,还有一项信息是常量池(constant pool),用于存放编译期产生的各种字面量和符号引用,该部分内容在类加载后进入方法区的运行时常量池中存放。运行时常量池相对于Class文件的常量池的一个重要特征就是具备动态性,即并不要求常量一定只在编译期产生,运行期间也可将常量放入池中。String类中的itern()方法就是这样一个例子,当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。它遵循以下规则:对于任意两个字符串 st,当且仅当 s.equals(t)true 时,s.intern() == t.intern() 才为 true。 当常量池无法再分配到足够的内存时将抛出OutOfMemoryError异常。

7.直接内存

  直接内存并不是虚拟机运行时数据区的一部分,也非虚拟机规范定义的内存区,但该部分内存会被频繁使用。直接内存不会受到虚拟机内存大小的限制,但会受本机内存大小的限制。因此也可能会抛出OutOfMemoryError异常。

JVM学习笔记-运行时数据区的更多相关文章

  1. 1、JVM 内存模型+运行时数据区+JVM参数

    JMM(内存模型)  1.’主内存+每个线程有自己的内存 JVM运行时数据区 包含:1.程序计算器(每个线程自带):2.JAVA-STACK(每个线程自带):3.本地方法stack:4.堆:5.方法区 ...

  2. jvm内存模型(运行时数据区)

    运行时数据区(runtime data area) jvm定义了几个运行时数据区,这些运行时数据区存储的数据,供开发者的应用或者jvm本身使用.按线程共享与否可以分为线程间共享和线程间独立. 线程间独 ...

  3. JVM三部曲之运行时数据区 (第一部)

    在接下来的几天想总结下,JVM相关的一些内容,比如下面的这三个内容算是比较核心知识点了 1.运行时数据区域: 在运行时数据区里存储类Class文件元数据(方法区),对象和数组(堆),方法参数局部变量( ...

  4. JVM内存结构——运行时数据区

    在Java虚拟机规范中将Java运行时数据划分为6种,分别为: PC寄存器(程序计数器) Java栈 堆 方法区 运行时常量池 本地方法栈 一.PC寄存器(程序计数器) PC寄存器(Program C ...

  5. JVM之Java运行时数据区(线程隔离区)

    来源 JVM会在会在执行Java程序过程中把所管理的内存划分为若干区域,主要包括程序计数器(Program Counter Register),虚拟机栈(VM Stack),本地方法栈(Native ...

  6. JVM之Java运行时数据区(线程共享区)

    JVM运行时区域各线程共享的区域包括堆区和方法区. 堆区 堆区最最主要的功能是存储对象实例[上篇也提到过],因此Java垃圾回收的主要战场就是在堆区,因此也有称为GC堆区.如果堆区的内存不够会出现Ou ...

  7. 【转】Java运行时数据区简介及堆与栈的区别

    理解JVM运行时的数据区是Java编程中的进阶部分.我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),但是如果我们了解JVM的内部实现和其运行时的数据区的工作机 ...

  8. JVM笔记【1】-- 运行时数据区

    目录 (一)java内存区域管理 1.1 程序计数器 1.2 虚拟机栈 1.3 本地方法栈 1.4 java堆 1.5 方法区 1.5.1 运行时常量池 (二)直接内存 (一)java内存区域管理 C ...

  9. 【JVM学习】2.Java虚拟机运行时数据区

    来源: 公众号: 猿人谷 这里我们先说句题外话,相信大家在面试中经常被问到介绍Java内存模型,我在面试别人时也会经常问这个问题.但是,往往都会令我比较尴尬,我还话音未落,面试者就会"背诵& ...

随机推荐

  1. [转]Angular, Backbone, or Ember: Which is Best for your Build?

    In order to choose which framework is right for your build, we've asked four important questions of ...

  2. Spark RDD概念学习系列之rdd持久化、广播、累加器(十八)

    1.rdd持久化 2.广播 3.累加器 1.rdd持久化 通过spark-shell,可以快速的验证我们的想法和操作! 启动hdfs集群 spark@SparkSingleNode:/usr/loca ...

  3. 8-6-Exercise

    HDU 1003    Max Sum 题意:给出一串数字,求出其中某段连续的数字之和最大的值,同时要输出起点的位置和终点的位置~~~ 方法一: 用sum记录某一段和的值,maxx为目前为止最大的su ...

  4. 大陆用户如何下载Google Play中的apk文件

    利用一些中转网站完成,具体原理可能是以手机虚拟机形式下载,然后提取app,给出下载链接,不过知不知道原理不重要,反正都是被墙. 这里给出测试可用的网站apkpure(20160714) http:// ...

  5. sql server 分组统计数据

    说明:group by是sql中对数据表中的数据进行分组的,在select列表中出现的字段必须全部出现在group by 字段中,出现在聚合函数中的字段在group by中可有可无,没有出现在sele ...

  6. 【转】[Android编程心得] Camera(OpenCV)自动对焦和触摸对焦的实现

    参考http://stackoverflow.com/questions/18460647/android-setfocusarea-and-auto-focus http://blog.csdn.n ...

  7. 基于Qt的第三方库和控件

    ====================== 基于Qt的第三方库和控件 ======================     libQxt --------   http://dev.libqxt.o ...

  8. windows7 'telnet'不是内部或外部命令--转载

    ['telnet'不是内部或外部命令,也不是可运行的程序或批处理文件]当你想用telnet命令时,发现提示这句话怎么办?其实很简单,接下来为大家介绍下如何使用 方法/步骤   一般只有windows7 ...

  9. is_numeric漏洞分析

    2014年,PHP中is_numeric函数十六进制绕过漏洞引发了一次安全问题 接下来,我们来分析一下这个漏洞的原理 函数介绍: is_numeric — 检测变量是否为数字或数字字符串. 函数原型: ...

  10. 字符串右移n位(C++实现)

    字符串右移n位(C++实现): // ShiftNString.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <i ...