关闭

理解JVM——Java内存区域

标签: JVMJava虚拟机内存区域JVM内存区域Java虚拟机内存区域
820人阅读 评论(2) 收藏 举报
分类:

 转载请注明出处:http://blog.csdn.net/anxpp/article/details/51920314,谢谢!

     知其然,知其所以然。

    了解Java的内存相关知识,还是有必要的。


1、概述

    我专业是嵌入式,所以自然对C++是比较了解的,但是后来自学的Java,其内存的自动管理(一开始也不是很习惯...),可谓减少了相当大的开发量。

    使用C++的时候,一不小心,就会造成相当严重的内存泄露,而这在Java中,看起来就美好多了,不过如果没有较好的编程习惯,也是有可能会造成内存泄露的,可参考:JAVA 内存泄露详解(原因、例子及解决)

    如果理解Java的内存分配,以及不同的内存区域,将使我们更容易编写出更出色的代码。

    本文介绍Java虚拟机在运行Java程序时的不同数据区。


2、运行时数据区

    下图描述的是Java虚拟机所管理的不同运行时数据区:

01

    这些不同的区域都有各自的用途。

    2.1、程序计数器

    学习汇编时,里面的程序计数器的值总是指向当前执行的下一个地址,Java虚拟机中的程序计数器也扮演这这样一个角色。

    这是一块比较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时,通过改变这个计数器的值,来选取下一条需要执行的字节码指令。

    程序计数器为分支、循环、跳转、异常处理和线程恢复等提供了基础支持。

    多线程中,单个处理器(即一个内核)任何时候都只能执行一条线程中的指令,Java是通过轮流切换线程并分配处理器执行时间的方式来实现的,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,个线程间的计数器互不影响,独立存储。所以这块内存区域是“线程私有”的内存。

    如果线程正在执行的是Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址。如果执行的是本地方法,这个计数器的值为空(Undefined)。

    Java虚拟机规范中对此区域没有规定任何OutOfMemoryError情况。

    2.2、虚拟机栈

    其实这块内存区域,称作Java方法栈会更容易理解。

    Java虚拟机栈也是线程私有的,生命周期与线程相同。

    虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(用于支持虚拟机进行方法调用和方法执行的数据结构),用于存储局部变量表、操作数栈、动态链接和方法出口等信息。每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

    局部变量表存放了编译器可知的各种基本数据类型(即8种Java基本数据类型),对象引用和returnAddress类型。

    当要进入一个方法时,这个方法需要在栈中分配多大的内存是完全确定的,并在编译期间就完成了分配,并在方法运行期间不会发生改变。long和double会占用2个局部变量空间,其他类型都只占用一个。

    在Java虚拟机规范中,该区域可能会发生两种异常

    1、StackOverFlowError:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出该异常。

    2、OutOfMemoryError:如果虚拟机栈动态扩展时,无法申请到足够的内存,会抛出OutOfMemoryError异常。

    对内存溢出异常的介绍,后面会专门写一篇文章,此处暂不多介绍。

    2.3、本地方法栈

     本地方法栈与Java虚拟机栈作用是相似的,不过它是为本地方法服务的。

     介于此,在很多虚拟机(如我们最常使用的Sun HotSpot)实现时将本地方法栈和虚拟机栈合二为一,当然,内存溢出情况也与Java虚拟机栈类似。

    2.4、堆

    这可能是我们最想关心的内存区域了,Java堆通常是Java虚拟机所管理的内存中最大的一块,是线程共享的,在虚拟机启动时创建。

    此内存区域唯一的目的就是存放对象实例,几乎(Java规范规定的是所有对象实例和数组)所有的对象实例都在这里分配内存。

    Java堆是垃圾回收器管理的主要区域,也常被称为GC堆。

    如果堆已经内有足够的内存以完成对象实例的分配,并且堆无法扩展时,会抛出OutOfMemoryError异常。

    2.5、方法区

    方法区是线程共享的,存储的是已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。因此,也常将方法区称为“永久代”。

    如果方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

    运行时常量池

    运行时常量池是方法区的一部分。

    Class文件中除了有类的版本、字段、方法、接口等信息,还有常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。

    因为运行时常量区也是方法区的一部分,所以如果常量区不发再申请到内存时,会抛出OutOfMemoryError异常。

    2.6、直接内存

    直接内存实际是JVM外的主机内存,不是虚拟机运行时数据区的一部分。

    这部分内存也常被频繁使用,也容易导致OutOfMemoryError异常。

    直接内存的分配不受Java堆大小的限制。

    但是在JVM的内存设置不合理时,比如各个内存区域综合大于物理内存时,动态扩展时就很容易出现OutOfMemoryError异常。

 

    其他的,之后在添加文章介绍吧。

1
0
查看评论

【深入理解JVM】:Java内存区域

JVM具有自动内存管理机制,Java不需要像c/c++一样,为每一个new操作写配对的delete/free代码,不容易出现内存泄露和溢出。JVM内存区域主要包括如下部分:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区。程序计数器程序计数器可以视为当前线程所执行的字节码行号指示器,如果...
  • u011080472
  • u011080472
  • 2016-05-05 09:50
  • 1813

JVM规范中的五大java内存区域

JVM在执行java程序时会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间。有的数据区域随着JVM的进程而启动,有的数据区域则依赖于用户线程的启动和结束而创建和销毁
  • canot
  • canot
  • 2016-03-31 16:07
  • 4186

【深入Java虚拟机】之一:Java内存区域与内存溢出

Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域。Java虚拟机规范将JVM所管理的内存分为以下几个运行时数据区:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区。下面详细阐述各数据区所存储的数据类型。 程序计数器(Program Counter...
  • mmc_maodun
  • mmc_maodun
  • 2013-12-30 08:20
  • 33162

Java内存管理:Java内存区域 JVM运行时数据区

Java内存管理:在前面的一些文章了解到javac编译的大体过程、Class文件结构、以及JVM字节码指令,下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些,然后分别介绍它们的特点,并指出给出一些HotSpot虚拟机实现的不同点和调整参数。
  • tjiyu
  • tjiyu
  • 2016-12-29 00:36
  • 4130

JVM线程内存区域划分

JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释
  • zly9923218
  • zly9923218
  • 2016-03-21 14:57
  • 523

【Java高级】JVM内存区域模型和加载过程

JVM内存区域模型    1.方法区 也称"永久代” 、“非堆”,  它用于存储虚拟机加载的类信息、常量、静态变量、是各个线程共享的内存区域。默认最小值为16MB,最大值为64MB,可以通过-XX:PermSize 和...
  • scboyhj__
  • scboyhj__
  • 2015-07-12 22:46
  • 1284

java进阶学习

开发者头条上看到的一篇好文,对于学习java是一条很好的提高路线。书单如何回答下列问题 synchronized与lock的区别,使用场景。看过synchronized的源码没 JVM自动内存管理,Minor GC与Full GC的触发机制 了解过JVM调优没,基本思路是什么 如何设计存储海量数据的...
  • u012248450
  • u012248450
  • 2016-04-01 13:57
  • 520

JVM内存区域详解

JVM内存模型总体架构图 程序计数器 多线程时,当线程数超过CPU数量或CPU内核数量,线程之间就要根据时间片轮询抢夺CPU时间资源。因此每个线程有要有一个独立的程序计数器,记录下一条要运行的指令。线程私有的内存区域。如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的...
  • qq_36859415
  • qq_36859415
  • 2016-11-30 14:22
  • 2253

Java内存区域理解

Java内存区域总览: Java虚拟机包括下面几个运行时数据区域:   Java虚拟机在执行Java的过程中会把管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,而有的区域则依赖线程的...
  • hanyuliang2000
  • hanyuliang2000
  • 2016-07-04 09:18
  • 317

[Java]理解JVM之一:JVM内存区域

一、数组内存分析
  • tengyunhao
  • tengyunhao
  • 2017-03-07 16:49
  • 86
    个人资料
    • 访问:785922次
    • 积分:5611
    • 等级:
    • 排名:第5594名
    • 原创:96篇
    • 转载:1篇
    • 译文:0篇
    • 评论:299条
    博客专栏
    其他信息
    music