Java虚拟机JVM中的内存区域的介绍

概述

jvm内存分为几个区域:
- 程序计数器
- 虚拟机
- 本地方法栈
- 堆
- 方法区
- 运行时常量池
- 直接内存

Java虚拟机JVM中的内存区域的介绍-上流阁
这些内存区域是在Java进程中细分的,为java程序提供服务
不同的区域存储的内容不一样,生命周期的也不一样

内存区域
程序计数器
这个就跟处理器中的程序计数器的功能差不多,是记录下一条字节码的地址
不过处理器的程序计数器是为进程服务的,jvm中的程序计数器是为线程服务的
所以jvm的程序计数器是线程私有的,声明周期和线程相同,各线程之间的程序计数器互不干扰
因为是记录下一条字节码的地址,所以不对java中native方法服务,native方法会直接开启一个进程,由cpu中的程序计数器来控制
程序计数器是jvm中唯一不会抛出OutOfmemoryError的区域

虚拟机栈
这个也跟cpu中的栈的作用差不多,进入方法时,在栈中入栈一个栈帧,栈帧中记录着局部变量表、操作数栈、动态链接、方法出口。当退出这个方法时,出栈当前栈帧
虚拟机栈因为面向方法服务,所以他是线程私有的

局部变量表
局部变量表中记录着方法中的局部变量的类型(如int,boolean,char,…,引用类型)和这个变量的内存地址

操作数栈
操作数栈相当于cpu中的通用寄存器,存放着被逻辑运算单元处理的值,很多指令都需要从这个区域读取值(add,cmp,mov,…)

方法出口
这里记录着处理完当前方法之后,执行的下一条指令的地址

本地方法栈
本地方法栈其实跟虚拟机栈差不多,只不过是面向native方法服务,虚拟机栈只对字节码服务


这个区域是绝大多数对象生活的地方。自然也是垃圾收集器的重点照顾对象。
该区域负责存储对象的实例,在这里进行对象的内存空间的分配。因为绝大多数对象都生活在这里,所以他是所有线程共享的区域。
堆还细分为新生代区域和老生代区域。新生代区域主要存活的是“朝生夕死”的对象,频繁的出生,又频繁的被消灭,这是被垃圾收集器集火的区域。老生代区域存活的需要稳定存活的对象,所以垃圾收集器比较少光顾这里。
绝大多数对象是存活时间较短的,既生活在新生代。所以新生代区域通常比老生代区域要大。

方法区
方法区记录着已加载类的信息。如全限定名(包名+类名)、方法、字段、描述符、参数、常量、静态变量。此区域也是被所有线程共享。
这个区域还有一个名称——永生代,意味着这个区域很少被清理。因为类的可清理幅度很小,以及判断一个类是否是不再被需要的类要求比较苛刻,所以垃圾收集器很少清理这个区域。

运行时常量池
这个区域记录着编译期生成的字面量和符号引用。同样也是被所有线程共享的。

字面量
字面量包括是被双引号”“标明的字符串,以及在代码中写死的一些基本数据类型,这些都属于常量。
在jdk1.6,运行时常量池是属于方法区的一部分。发现一个常量,首先检查运行时常量池中是否已经存放了这个常量,如果没有存放,则复制一份到运行时常量池中。以后每一次试图创建相同值的常量,都直接引用运行时常量池。
从jdk1.7开始,运行时常量池已经划分到了堆中。对于首次出现的常量,不再复制到运行时常量池,而是在运行时常量池中保留一份引用,指向首次出现常量的内存地址。

直接内存
这个区域其实上不是jvm的一部分,而且属于其他进程的。当调用一个native方法的时候,就可能会产生一份直接内存。
直接内存指的是在native方法中使用的那一块内存空间。比如NIO操作,它是使用native方法来读写文件的,这时就会产生一份直接内存指向读写文件的内存(缓存)。
注意直接内存并不在jvm中,但是会在jvm堆中保持一个引用,指向内存空间的直接内存。这样就避免了类似NIO操作频繁的从内存空间和java堆中来回复制数据。

*文章为作者独立观点,不代表上流阁立场
本文由 江风成 授权 上流阁 发表,并经上流阁编辑。转载此文章须经作者同意,并请附上出处(上流阁)及本页链接。原文链接https://www.o6c.com/java/2016/11/06/623.html
发表评论

坐等沙发
相关文章
Java技术中Mysql之Mybaitis中IN的函数拼接方法
Java技术中Mysql之Mybaitis中IN的函数拼…
java和安卓中对Map的key值和value值进行升序降序排序干货
java和安卓中对Map的key值和value值进行…
java用户metadata-extractor读取照片信息错误Exception in thread “main” java.lang.NoClassDefFoundError: com/adobe/xmp/XMPException
java用户metadata-extractor读取照片信…
eclipse导出可执行jar包并在Windows下用鼠标双击可运行
eclipse导出可执行jar包并在Windows下用…
MySQL数据库sql中字符串函数的字符串截取
MySQL数据库sql中字符串函数的字符串截取
双等于==运算符中的抽象相等比较算法使用
双等于==运算符中的抽象相等比较算法使用
javaweb开发程序员php开发,微信开发。接受定制开发

最新评论

  • 137博客

    每天醒来,敲醒自己的不是钟声,而

  • 137博客

    谢谢分享,我的博客,欢迎回访

  • 外星人

    爱美是人的天性,就连外星人也不例

  • 陈沩亮网络营销

    谢谢分享!我也想在手机移动端,实

  • shift

    我QQ也被冻永久啊,