Java虚拟机知识点整理总结一

 

1、程序计数器: 它可 以 看作 是 当前 线程 所 执行 的 字节 码 的 行号 指示器。字节 码 解释器 工作 时 就是 通过 改变 这个 计数器 的 值 来 选取 下一 条 需要 执行 的 字节 码 指令, 分支、 循环、 跳 转、 异常 处理、 线程 恢复 等 基础 功能 都 需要 依赖 这个 计数器 来 完成。

      线程 正在 执行 的 是 一个 Java 方法, 这个 计数器 记录 的 是 正在 执行 的 虚拟 机 字节 码 指令 的 地址; 如果 正在 执 行的 是 Native 方法, 这个 计数器 值 则为 空( Undefined)。此 内存 区域 是 唯一 一个 在 Java 虚拟 机 规范 中 没有 规定 任何 OutOfMemoryError 情况 的 区域。

2、Java虚拟机栈:线程 私有 的,(很多人把虚拟机内存区粗糙分为堆,栈,这个栈就是指虚拟机栈 或者 说是 虚拟 机 栈 中局 部 变量 表 部分。) 它的 生命 周期 与 线程 相同。 虚拟 机 栈 描述 的 是 Java 方法 执行 的 内存 模型: 每个 方法 在 执行 的 同时 都会 创建 一个 栈 帧 用于 存储 局部 变 量表、 操 作数 栈、 动态 链接、 方法 出口 等 信息。 每一个 方法 从 调用 直至 执行 完成 的 过程, 就 对应 着 一个 栈 帧 在 虚拟 机 栈 中 入栈 到 出 栈 的 过程。

      2.1:局部变量表:局部 变量 表 存放 了 编译 期 可知 的 各种 基本 数据 类型( boolean、 byte、 char、 short、 int、 float、 long、 double)、 对象 引用( reference 类型, 它不 等同 于 对象 本身, 可能 是一 个 指向 对象 起始 地址 的引用 指针 或者句柄

3、Java 堆: 是 Java 虚拟 机 所 管理 的 内存 中最 大的 一块。 Java 堆 是 被 所有 线程 共享 的 一块 内存 区域, 在 虚拟 机 启动 时 创建。 此 内存 区域 的 唯一 目的 就是 存放 对象 实例, 几乎 所有 的 对象 实例 都在 这里 分配 内存。

4、本地方法栈:与 虚拟 机 栈 所 发挥 的 作用 是非 常 相似 的, 它们 之间 的 区别 不过 是 虚拟 机 栈 为 虚拟 机 执行 Java 方法( 也就是 字节 码) 服务, 而 本地 方法 栈 则为 虚拟 机 使 用到 的 Native 方法 服务。

5、方法区:与 Java 堆 一样, 是 各个 线程 共享 的 内存 区域, 它 用于 存储 已被 虚拟 机 加载 的 类 信息、 常量、 静态 变量、 即时 编译器 编译 后的 代码 等 数据。

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

         Java 语言 并不 要求 常量 一定 只有 编译 期 才能 产生, 也就是 并非 预置 入 Class 文件 中 常量 池 的 内容 才能 进入 方法 区 运行时 常量 池, 运行 期间 也可 能将 新的 常量 放入 池 中, 这种 特性 被开发 人员 利用 得比 较多 的 便是 String 类 的 intern() 方法。会受制方法 区 内存 的 限制, 当 常量 池 无法 再 申请 到 内存 时会 抛出 OutOfMemoryError 异常。

6、直接内存:并不是 虚拟 机 运行时 数据区 的 一部分, 也不 是 Java 虚拟 机 规范 中 定义 的 内存 区域。 但是 这部 分 内存 也 被 频繁 地 使用, 而且 也可能 导致 OutOfMemoryError 异常 出现,可以通过存储 在 Java 堆 中的 DirectByteBuffer 对象 作为 这块 内存 的 引用 进行 操作。这样 能在 一些 场景 中 显著 提高 性能, 因为 避免 了 在 Java 堆 和 Native 堆 中 来回 复制 数据。

扫描二维码关注公众号,回复: 13565794 查看本文章

      本机 直接 内存 的 分配 不会 受到 Java 堆 大小 的 限制, 但还是 会受 到 本机 总 内存( 包括 RAM 以及 SWAP 区 或者 分页 文件) 大小 以及 处理器 寻址 空间 的 限制。 服务器 管理员 在 配置 虚拟 机 参数 时, 会 根据 实际 内存 设置- Xmx 等 参数 信息, 但 经常 忽略 直接 内存, 使得 各个 内存 区域 总和 大于 物理 内存 限制( 包括 物理 的 和 操作系统 级 的 限制), 从而 导致 动态 扩展 时 出现 OutOfMemoryError 异常。

猜你喜欢

转载自blog.csdn.net/q1035331653/article/details/90640644