Java内存区域管理详解
1 关于自动内存管理
- Java是由jvm来管理内存,包括自动分配以及自动回收,因此它不容易出现内存泄漏和内存溢出问题。
- C/C++,由程序员手动管理内存,手动完成:使用前申请内存,使用后释放内存。
2 运行时数据区域
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间。
Java虚拟机所管理的内存 包括以下几个运行时数据区域:
2.1 程序计数器
- 程序计数器(Program Counter Register):存储当前线程所执行的字节码指令的内存地址。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。【通过PC来寻找下一条要执行的指令】。
- 程序计数器是线程私有的。cpu通过轮流分配时间片来执行线程,为了线程切换后能恢复到正确的执行位置,显然每个线程都需要有一个独立的程序计数器。
- 如果线程正在执行的是一个Java方法,PC记录的是正在执行的字节码指令的地址;如果正在执行的是本地(Native)方法,这个计数器值则应为空。【todo 为什么本地方法时为空】
2.2 虚拟机栈
- 虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,jvm会同步创建一个栈帧[后续章节详解](Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。
- 虚拟机栈也是线程私有的,它的生命周期与线程相同。
2.2.1 局部变量表
JDK8之前,对jvm内存的认知只停留在:堆内存(Heap)和栈内存(Stack),而“栈”通常就是指这里讲的虚拟机栈,或者更多的情况下只是指虚拟机栈中局部变量表部分。
- 局部变量表存储:基本数据类型(八种:boolean、byte、char、short、int、 float、long、double)、对象引用(可能是一个指向对象起始 地址的引用指针)和returnAddress 类型(指向了一条字节码指令的地址)。
- 局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定 的,在方法运行期间不会改变局部变量表的大小。【这里的大小仅值变量槽的数量】
- 局部变量表以局部变量槽(Slot)来存储数据,其中64位长度的long和 double类型的数据会占用两个变量槽,其余的数据类型只占用一个。(通常一个槽占据N个字节,N大小由不同的虚拟机实现决定)。
关于栈的内存数据分析,在后续章节中会有更深入分析,在本节中这里仅引入概念。
2.2.2 操作数栈
关于方法调用时的进栈跟出栈的原理,在《深入理解计算机系统》系列笔记的后续章节中会进行总结。
2.3 本地方法栈
- 本地方法栈(Native Method Stacks)与虚拟机栈作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native) 方法服务。
- 线程私有的。
2.4 堆
- Java堆(Java Heap)存储对象的实例。
- Java堆是线程共享的,且比较大的一块内存区域,在虚拟机启动时创建。
- Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩展来实现的(通过参数-Xmx和-Xms设定)。
- 可弹性伸缩,但不会超过设定的最大容量,如果在Java堆中没有内存完成实例分配,并且堆也无法再 扩展时,Java虚拟机将会抛出OutOfMemoryError异常
- Java堆可以处于物理上不连续的内存空间中,但在逻辑上它应该 被视为连续的。
2.5 方法区
- 方法区存储已被虚拟机加载的class的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
- 方法区是线程共享。
- 方法区不需要连续的内存、可以选择固定大小或者可扩展,甚至还可以选择不实现垃圾收集(因为这部分内存通常不满足回收条件)
- 方法区无法满足新的内存分配需求时,将抛出 OutOfMemoryError异常。
2.5.1 运行时常量池
- 存放编译期生成的各种字面量与符号引用
- 运行时常量池(Runtime Constant Pool)是方法区的一部分
3 直接内存
- 首先,直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中 定义的内存区域
- 它可能导致OutOfMemoryError异常出现,有必要了解。
在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区 (Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的 DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了 在Java堆和Native堆中来回复制数据。
显然,本机直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,则肯定还是会受到 本机总内存(包括物理内存、SWAP分区或者分页文件)大小以及处理器寻址空间的限制,一般服务 器管理员配置虚拟机参数时,会根据实际内存去设置-Xmx等参数信息,但经常忽略掉直接内存,使得 各个内存区域总和大于物理内存限制(包括物理的和操作系统级的限制),从而导致动态扩展时出现 OutOfMemoryError异常。
4 总结
Java内存区域及其数据类别概览:
到此这篇关于Java内存区域管理详解的文章就介绍到这了,更多相关Java内存区域管理内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
原文出处:https://blog.51cto.com/u_15773567/5690345
相关文章
- 这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
java 运行报错has been compiled by a more recent version of the Java Runtime
java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01- 这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
- 这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
- 说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
- 这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
- 这篇文章主要介绍了浅谈redis key值内存消耗以及性能影响,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-07
- 这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
java 画pdf用itext调整表格宽度、自定义各个列宽的方法
这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31- 这篇文章主要介绍了详解分析MySQL8.0的内存消耗,帮助大家更好的理解和学习使用MySQL,感兴趣的朋友可以了解下...2021-03-23
- 这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
- 这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
- 这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
Java使用ScriptEngine动态执行代码(附Java几种动态执行代码比较)
这篇文章主要介绍了Java使用ScriptEngine动态执行代码,并且分享Java几种动态执行代码比较,需要的朋友可以参考下...2021-04-15- 这篇文章主要介绍了Java开发实现人机猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-03
Java 8 Stream 的终极技巧——Collectors 功能与操作方法详解
这篇文章主要介绍了Java 8 Stream Collectors 功能与操作方法,结合实例形式详细分析了Java 8 Stream Collectors 功能、操作方法及相关注意事项,需要的朋友可以参考下...2020-05-20- 这篇文章主要介绍了Java List集合返回值去掉中括号('[ ]')的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-29
Java中lombok的@Builder注解的解析与简单使用详解
这篇文章主要介绍了Java中lombok的@Builder注解的解析与简单使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-06- 这篇文章主要介绍了解决使用OpenCV中的imread()内存报错问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16