了解虚拟机是怎么使用内存的,有助于我们解决和排查内存泄漏和溢出方面的问题。详解java虚拟机内存的各个区域,分析这些区域的作用服务对象以及可能发生的问题。

一、运行时数据区域

  java虚拟机在执行java程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域。这些数据区域都有各自的用途,以及创建时间和销毁时间。有的随着虚拟机进程的而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。根据java虚拟机的规范,jvm管理的内存将包括以下几个运行时数据区域。

1.1 程序计数器

  程序计数器是当前线程所执行程序字节码的行号计数器,字节码解释器根据这个程序计数器的值来选取下一条需要执行的字节码,实现程序的分支、循环、跳转、异常处理 和线程控制等基本功能。在java中,每个线程的执行需要操作系统轮换的分配处理机,因此每个线程都有自己的程序计数器,各个线程之间的计数器互不影响,独立存储,计数器占用空间不大。因此计数器是线程私有的内存。当线程正在执行java方法时,计数器的值为当前字节码指令的地址。当执行的是本地方法是,计数器的值为空。计数器是唯一一个不会发生OOM的数据区域。

1.2 java虚拟机栈

  虚拟机栈和计数器一样,和线程私有的,它的生命周期和线程相同。虚拟机栈是java方法执行的内存描述:每一个方法的执行都会为其创建一个栈帧,用于存储局部变量表,操作数栈,动态链接和方法的出口信息,局部变量表存储了编译期可知的基本数据类型[byte,int,float,double,char,short,long,boolean],对象引用类型(不是实际的对象,可能只是对象的内存地址),进入一个方法后,局部变量表的内存空间在编译是完全确认的,方法运行期间不会改变其大小。每一个方法从调用到执行完成,都对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

  该区域可能有两类异常:StackOverflowError:线程请求的深度大于虚拟机允许的深度;OutOfMemory:如果虚拟机栈可以动态扩展,但是扩展的时候无法申请到足够的内存。

1.3 本地方法栈

  与java虚拟机栈类似,但是不同的是Java虚拟机栈是为java方法服务(字节码),本地方法栈是为非java语言但是虚拟机又使用到的方法服务的(比如类加载器中最顶层的实现使用的是c++)。同样的,本地方法栈也会抛出StackOverflowErrorOutOfMemory异常。

1.4 java堆

  java堆是被所有线程共享的一大片内存区域,其作用就是为创建的实例对象或者数组分配内存,也因此java堆是GC的主要针对区域,为了更好实现GC的效果,还把这一大块java堆内存分为不同的区域:叫什么Eden区,From区,Survivor,To Survivor;还有的从线程的角度甚至把这线程共享的java堆给各个线程分配了自己的缓冲区。真是树大招风啊!!但是无论java堆内存从什么角度被怎么划分,在这java堆中存放实例对象或者数组这一事实无法更改。进一步划分的目的是为了更加高效滴利用这一内存中的宝地罢了。根据规范,java堆的内存在物理上不要求连续,只要逻辑上连续就好了。

  该区域可能抛出的异常:OutOfMemory:堆中没有内存足以给实例分配了

1.5 方法区

  与java堆一样,也是线程共享的内存区域,主要用于存放已经被虚拟机加载的类信息常量静态变量,以及实时编译的数据。虽然我们很不愿意把方法区和java堆混为一谈,但是从GC的角度,GC就是将方法区看成是java堆的永久代。虽然GC在这“永久代”上的效果总不是那么理想,但是却必不可少,GC在永久代的目的是针对常量池的回收以及类型卸载。

  该区域可能出现的异常:OutOfMemory:方法区无法满足内配时。

1.6 运行时常量池

  线程共享的内存区域,运行时常量池属于方法区的一部分。java文件编译的Class文件中,除了类的基本信息(版本,字段,方法,接口等)之外,还有就是常量池,用于存放编译期间生成的字面量和符号引用(我觉得就是static,final修饰的字段吧),这部分内容在类被加载后就被放入运行时常量池了。除了Class文件中的符号引用外,还把翻译出来的直接引用也存储在运行时常量池了。运行时常量池还可以动态滴加入程序运行时生成的常量,比如String。

  运行时常量池是方法区的一部分,那么自然也受到方法区内存的限制,当无法申请到内存时将抛出OutOfMemory。

二、直接内存

  直接内存并不是java虚拟机运行时数据区域的一部分,也不是虚拟机规范中定义的内存区域,但是这部分内存常常也被频繁使用,而且也可能导致OutOfMemory,直接内存的分配虽然不受java堆大小的限制,但是既然是内存,那么必然受到本机物理内存的限制,我们在配置java虚拟机内存的时候,一定要注意java虚拟机各部分的内存总和不能大于本机实际的物理内存。

三、No Picture You Say a j8

[jvm]运行时数据区域详解的更多相关文章

  1. JVM运行时数据区域详解

    参考文章: <Java Se11 虚拟机规范> <深入理解Java虚拟机-JVM高级特性与最佳实践 第3版>- 周志明 本文基于Java Se 11讲解. 根据<Java ...

  2. JVM——内存区域:运行时数据区域详解

    关注微信公众号:CodingTechWork,一起学习进步. 引言   我们经常会被问到一个问题是Java和C++有何区别?我们除了能回答一个是面向对象.一个是面向过程编程以外,我们还会从底层内存管理 ...

  3. JVM 运行时数据区详解

    一.运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同数据区域. 1.有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,所有的线程共享这些数据区. 2.第二种则 ...

  4. JVM运行时数据区域

    上面已经聊过JVM是什么东东,也谈过了JVM内存的垃圾回收机制.这一篇博客我们来聊聊JVM运行时数据区域. JVM运行时数据区域由5块部分组成,分别是堆,方法区,栈,本地方法栈,以及程序计数器组成. ...

  5. 深入理解Java虚拟机 -- 读书笔记(1):JVM运行时数据区域

    深入理解Java虚拟机 -- 读书笔记:JVM运行时数据区域 本文转载:http://blog.csdn.net/jubincn/article/details/8607790 本系列为<深入理 ...

  6. JVM 运行时数据区域划分

    目录 前言 什么是JVM JRE/JDK/JVM是什么关系 JVM执行程序的过程 JVM的生命周期 JVM垃圾回收 JVM的内存区域划分 一.运行时数据区包括哪几部分? 二.运行时数据区的每部分到底存 ...

  7. Java 虚拟机运行时数据区详解

    本文摘自深入理解 Java 虚拟机第三版 概述 Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟 ...

  8. JVM 运行时数据区域

    Java虚拟机管理的内存包括以下几个运行时数据区域: 1.程序计数器: 程序计数器是一块比较小的内存空间,是当前线程执行的字节码行号指示器.Java多线程是通过线程轮流切换来实现的,所以每个线程都有一 ...

  9. 深入理解Java虚拟机-JVM运行时数据区域

    一.运行时数据区域 1.程序计数器 程序计数器( Program Counter Register) 是一块较小的内存空间, 它可以看作是当前线程所执行的字节码的行号指示器. Java虚拟机的多线程是 ...

随机推荐

  1. 浅谈c/c++中的指针问题

    首先给出几种指针类型来作出区分,不看后面的解析如果可以自己分辨正确那么就算对指针有一个很好的掌握了,就没有必要再去看后面的解析,如果不能完全区分,那么就有必要仔细看看后面解析. 1 Char * p  ...

  2. unary_function和binary_function详解

    1.unary_function和binary_function介绍 1.1 unary_function介绍 unary_function可以作为一个一元函数对象的基类,它只定义了参数和返回值的类型 ...

  3. Photo4

    Story: 我手捧玫瑰,一个人,走在桥上.桥下是波澜壮阔的大海,一不小心,我就有失足的危险.海鸟的低鸣在我耳际盘旋着,浪汹涌,仿佛要把我吞噬掉.你也许奇怪,为何我一人手捧玫瑰走在桥上.只因,女骑从来 ...

  4. position与offset的区别

    .offset()是相对于文档(document)的当前位置,.position()是相对于父级元素的位移,一个元素可以嵌套多个position

  5. PHP json_encode中文unicode转码问题

    用PHP的json_encode来处理中文的时候, 中文都会被编码, 变成不可读的, 类似”\u***”的格式,如果想汉字不进行转码,这里提供三种方法 1.升级PHP,在PHP5.4, 这个问题终于得 ...

  6. Dubbo的配置及启动

    Tomcat+Dubbo安装 1.将tomcat的webapps目录下的所有文件清空,讲Dubbo管理控制台的程序dubbo-admin-2.5.3.war放 到webapps中,并且解压命名为ROO ...

  7. 使用virtualBox安装CentOS 6.3的详细步骤

    由于前几天把系统升级到win7了,原先安装的Linux虚拟机都不存在了.基于学习,这次安装选择的是CentOS 6.3版本. 下面就看看具体的安装步骤: 名称可以随便填写,类型选择Linux,版本选择 ...

  8. 解决jeesite开发java.lang.String cannot be cast to com.thinkgem.jeesite.modules.sys.security.SystemAuthorizingRealm$Principal问题

    解决jeesite问题java.lang.String cannot be cast to SystemAuthorizingRealm问题 这些天在jeesite项目上进行二次开发,遇到许多莫名其妙 ...

  9. CodeForces 814D An overnight dance in discotheque(贪心+dfs)

    The crowdedness of the discotheque would never stop our friends from having fun, but a bit more spac ...

  10. 洛谷P2173 [ZJOI2012]网络(10棵lct与瞎jb暴力)

    有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环,同色的环指相同颜色的边构成的环. 在这个图上,你 ...