深入了解Java虚拟机——JVM内存分配
来源:互联网 发布:qq软件宣传语 编辑:程序博客网 时间:2024/06/01 09:28
相关引用:
字符串编译期与运行期分析及字符串常量池
Java虚拟机—–方法区和运行时常量池
JVM-String常量池与运行时常量池
深入理解Java虚拟机笔记—运行时栈帧结构
JVM内存分配
Java虚拟机将在Java程序运行过程中将内存分为不同的数据区域,每个区域都有自己的用途以及生命周期,大致划分如下图:
1. 程序计数器(线程私有)
占用很小的内存,可以看做当前线程执行的行号指示器,可以根据程序计数器来获取下一条需要执行的字节码指令。
由于java虚拟机的多线程是根据线程轮流切换的并分配处理器执行时间的方式来执行的,而每个线程的执行是相互隔离的,故每个线程都需要一个程序计数器来指示线程执行位置。故程序计数器为线程私有。
如果正在执行的是一个java方法,那么程序计数器指向的是当前正在执行的字节码指令的地址,如果正在执行的是一个本地方法,那么程序计数器指向空。
程序计数器创建是会分配固定内存,故此区域是唯一一个不会抛出OutOfMemoryError的区域。
此区域完全没有GC的必要。
2. 方法区(线程公有)
存储已被虚拟机加载的类信息,常量,静态变量,静态方法等数据。
从它存储的数据信息来看,它必须是线程共享的对吧。
由于该区域存储的数据被释放的可能性极小,所以GC 极少或完全不会 对该区域进行垃圾回收(根据虚拟机来定),即使回收,其主要目标是常量池或者类型的卸载。
3.运行时常量池
方法区的一部分
线程共享
虚拟机加载Class后把常量池中的数据放入到运行时常量池。
注 : 此处需要了解三个概念
1. 常量池 : 常量池在数据编译期被确定,存储的是类,接口,方 法中的常量,当然也包括字符串常量。可以理解为类的资源仓库。主要存储字面量和符号引用。
2. 运行时常量池: 虚拟机加载后把常量池中的数据放入的运行时常量池。运行期间新的常量也可以放入运行时常量池。
3. 字符串常量池: 常量池的一部分,存储的是编译期以及运行期产生的字符串数据。1.7以后被移到了堆中。
字面量与符合引用的解释
字面量 : 文本字符串,声明为final的常量值等。
符号引用: 类和接口的完全限定名,字段的名称和描述符,方法的名称和描述符。
4. 虚拟机栈(线程私有)
生命周期为线程的生成到消亡。
描述的是java方法执行的内存模型:每个方法执行的同时会在在虚拟机栈中创建一个栈帧,栈帧包含的内容有:局部变量表,操作数栈,动态链接,方法出口等信息。每个方法从开始到执行完成的过程,都是一个栈帧从入栈到出栈的过程。
虚拟机栈中规定了两张异常状况:如果栈深度大于JVM允许的深度时会抛出StackOverflowError。如果动态扩容时拿不到足够的内存,则会抛出OutOfMemoryError。
局部变量表 : 存放编译期可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double)以及引用类型,其中64位的double和long会分配两个局部变量空间,其余的只会分配一个。当执行一个方法时,这个方法的栈帧中局部变量表所占的内存空间是确定的,运行期间不会改变。
操作数栈 : 抱歉,这个概念目前不是很了解,如果有大神知道的话求解答。
动态链接 : 在说明什么是动态连接之前先看看方法的大概调用过程,首先在虚拟机运行的时候,运行时常量池会保存大量的符号引用,这些符号引用可以看成是每个方法的间接引用,如果代表栈帧A的方法想调用代表栈帧B的方法,那么这个虚拟机的方法调用指令就会以B方法的符号引用作为参数,但是因为符号引用并不是直接指向代表B方法的内存位置,所以在调用之前还必须要将符号引用转换为直接引用,然后通过直接引用才可以访问到真正的方法,这时候就有一点需要注意,如果符号引用是在类加载阶段或者第一次使用的时候转化为直接应用,那么这种转换成为静态解析,如果是在运行期间转换为直接引用,那么这种转换就成为动态连接。
方法出口 : 当一个方法被执行完后,有两种方式退出这个方法。第一种是正常执行完成后,根据返回类型判断将返回值传递给上层调用者。第二种是出现异常导致方法退出,不会产生任何返回值。
无论哪种情况,都要回到方法被调用的位置,方法退出等于把当前栈帧出栈,因此可能执行的操作有:恢复上层的局部变量表和操作数栈,把返回值(如果有的话)压入到栈帧的操作数栈中,程序计数器的值执行下一条指令。
5. 本地方法栈(线程私有)
- 和虚拟机栈区别在于虚拟机栈是为java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。
6. 堆(线程公有)
内存最大的一块。
GC的重点关注对象
几乎唯一的目的就是存放对象实例和数组
内存分配时,在物理上可以不连续,但逻辑上必须连续。
当堆内存空间不足以创建实例对象时,会抛出OutOfMemoryError。
- 深入了解Java虚拟机——JVM内存分配
- 深入理解Java虚拟机——JVM的内存结构和内存分配策略
- 深入理解Java虚拟机——JVM的内存结构和内存分配策略
- 深入了解Java虚拟机读书笔记(一)JVM内存区域
- 深入Java虚拟机——JVM内存详解
- 深入Java虚拟机——JVM内存详解
- 《深入理解java虚拟机》读书笔记——jvm内存区域
- 深入理解JVM(2)—Java虚拟机内存区域
- 深入了解JVM—内存区域
- 深入了解JVM—内存区域
- 深入了解JVM—内存区域
- JVM虚拟机内存分配
- 深入了解Java虚拟机之垃圾收集器和内存分配策略
- 深入理解Java虚拟机JVM高级特性与最佳实践阅读总结——第三章垃圾收集器与内存分配策略
- Java内存区域分配、存储、垃圾回收策略与回收机制(深入JVM虚拟机)
- 《深入理解Java虚拟机》读后总结 (二)JVM内存分配
- JAVA基础——深入了解JVM。
- 《深入理解Java虚拟机》——内存自动管理:内存分配与回收
- Android开发(1)click button
- 同步和异步的区别
- JS实现将数字金额转换为大写人民币汉字的方法
- Laravel的Nginx重写规则完整代码
- 一点总结
- 深入了解Java虚拟机——JVM内存分配
- linux查找一定时间范围内的shell文件
- 虚拟机和主机无法复制解决
- java.io.File类
- Microsoft SQL Server学习(二)--数据库的语法
- iOS 开发
- MT6572M不支持导出720P视频
- 论文阅读理解
- 无权图的最短路径