首页 > 编程语言 > 详细

Java内存区域

时间:2021-02-20 12:02:07      阅读:26      评论:0      收藏:0      [点我收藏+]

运行时数据区域

  • Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域

  • 这些区域有各自的用途,创建以及销毁的时间

  • 有的区域随着虚拟机进程的启动一直存在

  • 有些区域依赖用户线程的启动和结束而建立和销毁

技术分享图片

1、程序计数器

  • 计数器的功能

    • 当前线程所执行的字节码的行号指示器

  • 计数器的工作

    • 字节码解释器在工作时通过改变这个计数器的值,选取下一条需要执行的字节码指令

    • 程序控制流的指示器

      • 分支、循环、跳转、异常处理、线程恢复等基础功能都依赖于程序计数器

  • 线程私有

    • 在任何一个确定的时间,一个处理器(多核处理器的一个内核)都只会执行一条线程中的指令

    • 每个线程拥有独自的程序计数器可以保证线程切换后可以恢复到正确的执行位置

  • 计数器的值

    • 线程正在执行Java方法时,计数器记录的是正在执行的虚拟机字节码指令的地址

    • 线程正在执行本地(Native)方法时,计数器值为空(Undefined)

 

2、Java虚拟机栈

  • 线程私有

  • 生命周期线程相同

  • 功能

    • 描述Java方法执行的线程内存模型

    • 每个方法被执行的时候都会同步创建一个栈帧

       技术分享图片

    • 每个方法被调用直至执行完毕的过程,对应着一个栈帧从虚拟机栈中入栈到出栈的过程

  • 局部变量表存储内容

    • 编译期可知的各种基本数据类型

    • 对象引用

      • 可能是一个指向对象起始地址的引用指针

      • 可能是指向一个代表对象的句柄或者其他与此对象相关的位置

    • returnAddress类型

      • 指向一条字节码指令的地址

  • 异常状况

    • StackOverflowError

      • 线程请求的栈深度大于虚拟机所允许的栈深度

    • OutOfMemoryError

      • 栈扩展时无法申请到足够的内存

 

3、本地方法栈

  • 服务于虚拟机使用到的本地方法

  • 和Java虚拟机栈的功能类似

  • 异常状况

    • StackOverflowError

      • 线程请求的栈深度大于虚拟机所允许的栈深度

    • OutOfMemoryError

      • 栈扩展时无法申请到足够的内存

 

4、Java堆

  • 线程共享

  • 虚拟机启动时被创建

  • 存放对象实例

  • Java堆可以处于物理上不连续的内存空间中

  • Java堆可以是固定的,也可以是可扩展的(-Xmx和-Xms参数实现)

  • 异常状况

    • OutOfMemoryError

      • 在Java堆中没有内存可以进行实例分配,堆也无法再扩展时

 

5、方法区

  • 线程共享

  • 存储内容

    • 已被虚拟机加载的类型信息,如类名,字段描述,方法描述

    • 常量

    • 静态变量

    • 即时编译器编译后的代码缓存

  • 可以处于物理上不连续的内存空间中

  • 可以是固定的,也可以是可扩展的,还可以选择不实现垃圾回收

  • OutOfMemoryError

    • 方法区无法满足新的内存分配需求时

 

6、运行时常量池

  • 方法区的一部分

  • Class文件

    • 类的版本

    • 字段

    • 方法

    • 接口等描述信息

    • 常量池表

      • 存放编译期生成的各种字面量与符号引用

  • 动态性

    • 运行期间也可以将新的常量放入池中

      如String类的intern()方法

      • 把字符串对象加入常量池中

      • 让有相同值的引用指向同一个位置

      • 如果引用值变化了,但是常量池中没有新的值,那么就会新开辟一个常量结果来交给新的引用

      • 当常量池中不存在这个字符串的引用时,将这个对象的引用加入常量池,返回这个对象的引用

      • 当常量池中存在这个字符串的引用,返回这个对象的引用

  • OutOfMemoryError

    • 常量池无法再申请到内存时

 

直接内存

  • 不是虚拟机运行区域的一部分

  • NIO类

    • 一种基于通道与缓冲区的I/O方式

    • 使用Native函数库直接分配堆外内存,通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作

    • 避免了在Java堆和Native堆中来回复制数据

  • OutOfMemoryError

    • 服务器管理员在配置虚拟机参数时,会根据实际内存区设置参数信息,忽略掉直接内存,造成各个内存区域总和大于物理内存限制,导致动态扩展时出现异常

Java内存区域

原文:https://www.cnblogs.com/LittleSkinny/p/14419902.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!