1 关于自动内存管理

  1. Java是由jvm来管理内存,包括自动分配以及自动回收,因此它不容易出现内存泄漏和内存溢出问题。
  2. C/C++,由程序员手动管理内存,手动完成:使用前申请内存,使用后释放内存。

2 运行时数据区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间。

Java虚拟机所管理的内存 包括以下几个运行时数据区域:

2.1 程序计数器

  1. 程序计数器(Program Counter Register):存储当前线程所执行的字节码指令的内存地址。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。【通过PC来寻找下一条要执行的指令】。
  2. 程序计数器是线程私有的。cpu通过轮流分配时间片来执行线程,为了线程切换后能恢复到正确的执行位置,显然每个线程都需要有一个独立的程序计数器
  3. 如果线程正在执行的是一个Java方法,PC记录的是正在执行的字节码指令的地址;如果正在执行的是本地(Native)方法,这个计数器值则应为空。【todo 为什么本地方法时为空】

2.2 虚拟机栈

  1. 虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,jvm会同步创建一个栈帧[后续章节详解](Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息
  2. 虚拟机栈也是线程私有的,它的生命周期与线程相同。

2.2.1 局部变量表

JDK8之前,对jvm内存的认知只停留在:堆内存(Heap)和栈内存(Stack),而“栈”通常就是指这里讲的虚拟机栈,或者更多的情况下只是指虚拟机栈中局部变量表部分。
  1. 局部变量表存储:基本数据类型(八种:boolean、byte、char、short、int、 float、long、double)、对象引用(可能是一个指向对象起始 地址的引用指针)和returnAddress 类型(指向了一条字节码指令的地址)。
  2. 局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定 的,在方法运行期间不会改变局部变量表的大小。【这里的大小仅值变量槽的数量】
  3. 局部变量表以局部变量槽(Slot)来存储数据,其中64位长度的long和 double类型的数据会占用两个变量槽,其余的数据类型只占用一个。(通常一个槽占据N个字节,N大小由不同的虚拟机实现决定)。

关于栈的内存数据分析,在后续章节中会有更深入分析,在本节中这里仅引入概念。

2.2.2 操作数栈

关于方法调用时的进栈跟出栈的原理,在《深入理解计算机系统》系列笔记的后续章节中会进行总结。

2.3 本地方法栈

  1. 本地方法栈(Native Method Stacks)与虚拟机栈作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native) 方法服务
  2. 线程私有的。

2.4 堆

  1. Java堆(Java Heap)存储对象的实例
  2. Java堆是线程共享的,且比较大的一块内存区域,在虚拟机启动时创建
  3. Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩展来实现的(通过参数-Xmx和-Xms设定)。
  4. 可弹性伸缩,但不会超过设定的最大容量,如果在Java堆中没有内存完成实例分配,并且堆也无法再 扩展时,Java虚拟机将会抛出OutOfMemoryError异常
  5. Java堆可以处于物理上不连续的内存空间中,但在逻辑上它应该 被视为连续的。

2.5 方法区

  1. 方法区存储已被虚拟机加载的class的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
  2. 方法区是线程共享
  3. 方法区不需要连续的内存、可以选择固定大小或者可扩展,甚至还可以选择不实现垃圾收集(因为这部分内存通常不满足回收条件)
  4. 方法区无法满足新的内存分配需求时,将抛出 OutOfMemoryError异常。

2.5.1 运行时常量池

  1. 存放编译期生成的各种字面量与符号引用
  2. 运行时常量池(Runtime Constant Pool)是方法区的一部分

3 直接内存

  1. 首先,直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中 定义的内存区域
  2. 它可能导致OutOfMemoryError异常出现,有必要了解。
在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区 (Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的 DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了 在Java堆和Native堆中来回复制数据。

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

关于内存的深入了解,在《深入理解计算机系统》系列笔记的后续章节中会进行总结。

4 总结

Java内存区域及其数据类别概览:

1 Java内存区域管理的更多相关文章

  1. 【转】Java内存管理:深入Java内存区域

    转自:http://www.cnblogs.com/gw811/archive/2012/10/18/2730117.html 本文引用自:深入理解Java虚拟机的第2章内容 Java与C++之间有一 ...

  2. Java内存管理:深入Java内存区域

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 对于从事C和C++程序开发的开发人员来说,在内存管理领域,他们既是拥有最高权力的皇帝 ...

  3. java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)

    概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...

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

    转自:https://blog.csdn.net/tjiyu/article/details/53915869 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些, ...

  5. JVM自动内存管理机制——Java内存区域(下)

    一.虚拟机参数配置 在上一篇<Java自动内存管理机制——Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...

  6. Java内存管理(一):深入Java内存区域

    本文转自:http://www.cnblogs.com/gw811/archive/2012/10/18/2730117.html#undefined 推荐查看原文,原文格式更好一些. 本文引用自:深 ...

  7. 2.1 自动内存管理机制--Java内存区域与内存溢出异常

    自动内存管理机制 第二章.Java内存区域与内存溢出异常 [虚拟机中内存如何划分,以及哪部分区域.什么样代码和操作会导致内存溢出.各区域内存溢出的原因] 一.运行时数据区域 Java虚拟机所管理的内存 ...

  8. 深入理解java虚拟机读书笔记--java内存区域和管理

    第二章:Java内存区域和内存溢出异常 2.2运行时数据区域 运行时数据区分为方法区,堆,虚拟机栈,本地方法栈,程序计数器 方法区和堆是线程共享的区域 虚拟机栈,本地方法栈,程序计数器是数据隔离的数据 ...

  9. Java 内存区域和GC机制分析

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

随机推荐

  1. Linux YUM yum-utils 模块详解

    yum-utils 详解 yum-utils是yum的工具包集合,由不同的作者开发,使yum使用起来更加方便和强大.包括:debuginfo-install,find-repos-of-install ...

  2. 记录自己NVIDIA GeForce MX250迷之安装cuda+pytorch成功了

    电脑是ubuntu20.4 Pop!_OS 20.04 LTS MX250显卡并没有列在CUDA支持的GPU里 希望文中链接的别人的博客不会消失掉. 安装了英伟达的驱动 参考了这一篇:Ubuntu 安 ...

  3. 研发效能|Kubernetes核心技术剖析和DevOps落地经验

    本文主要介绍Kubernetes 的核心组件.架构.服务编排,以及在集群规模.网络&隔离.SideCar.高可用上的一些使用建议,尤其是在CICD中落地,什么是 GitOps. 通过此文可彻底 ...

  4. Grid属性太多记不住?【Grid栅格布局可视化编辑器】直观易懂高效,拖拉拽,有手就行!

    手把手教你通过拖拉拽可视化的方式带你练习[Grid栅格布局]的各个属性,直观易懂!再也不愁记不住繁多的Grid属性了.整个过程在众触应用平台进行,不用手写一行CSS代码. grid-auto-flow ...

  5. Template -「高斯消元」

    #include <cstdio> #include <vector> #include <algorithm> using namespace std; doub ...

  6. SpringCloud gateway自定义请求的 httpClient

    本文为博主原创,转载请注明出处: 引用 的 spring cloud gateway 的版本为 2.2.5 : SpringCloud gateway 在实现服务路由并请求的具体过程是在 org.sp ...

  7. 2506-nginx的配置-域名分发与负载均衡(只有配置无原理)

    nginx的安装 Windows7:官网下载,是一个压缩包,运行解压缩后的exe文件即启动了nginx,需注意的是,Windows(win7)的80端口默认被微软的IIS占用,需改成别的端口,例如80 ...

  8. linux rz上传失败

    最近rz上传文件时出现了一次文件上传失败的情况,故搜集了以下资料加强学习 rz -ary --o-sync -a 表示使用ascii码格式传输文件,如果是Dos格式的文件,会转换为unix格式 -r ...

  9. 【原创】Python 懂车帝口碑爬虫

    本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! 懂车帝综合口碑 需求 操作环境 win1 ...

  10. 羽夏看Linux内核——引导启动(下)

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...