【JVM】01虚拟机内存模型
学习链接:https://blog.csdn.net/u010425776/article/details/51170118
博主整理的条理清晰,在这里先感谢博主分享
去年看视频学习写过一篇JVM的博客,今年已经忘得精光,归根结底是没有结合实践深入理解,为加深记忆,手打重新整理一下,一边思考,加深理解:
JVM内存模型
Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是:
1. 程序计数器
2. Java虚拟机栈
3. 本地方法栈
4. 堆
5. 方法区。
1、程序计数器:
1.1什么是程序计数器:
程序计数器是较小的一块内存空间,记录了当前线程执行到的字节码文件的行号
1.2、程序计数器的作用:
1、字节码解释器通过改变程序计数器依次读取指令,实现代码流程控制,如顺序执行,循环等
2、多线程情况下记录当前线程执行到的位置,方便线程激活时继续执行
1.3、程序计数器的特点:
1、是一片较小的存储空间
2、线程私有,每条线程都有自己的程序计数器
3 、是唯一一个不会出现OutOfMemoryError的内存区域
4、生命周期随线程的创建而创建,随现成的销毁而销毁
2. Java虚拟机栈(JVM Stack)
2.1什么是java虚拟机栈:
java虚拟机栈是描述方法运行过程的内存模型
2.2java虚拟机栈的作用:
java虚拟机栈会为每个即将运行的方法分配内存,称作栈帧,存储运行过程中需要的一些信息。
包括:
1、局部变量表(基本数据类型、引用引用数据类型变量(内存地址?)、returnAddress(没听过))
2、操作数栈
3、动态链接
4、方法出口信息
5、等
2.3过程与特点:
当一个方法即将被运行时,Java虚拟机栈首先会在Java虚拟机栈中为该方法创建一块“栈帧”,栈帧中包含局部变量表、操作数栈、动态链接、方法出口信息等。当方法在运行过程中需要创建局部变量时,就将局部变量的值存入栈帧的局部变量表中(看不懂)。
当这个方法执行完毕后,这个方法所对应的栈帧将会出栈,并释放内存空间。
注意:人们常说,Java的内存空间分为“栈”和“堆”,栈中存放局部变量,堆中存放对象。
这句话不完全正确!这里的“堆”可以这么理解,但这里的“栈”只代表了Java虚拟机栈中的局部变量表部分。真正的Java虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息.
3.本地方法栈
与虚拟机栈类似,好像是用于native修饰的本地方法balabala~
4.堆
4.1什么是堆与堆的作用:
堆是用来存放对象的内存空间,几乎所有的对象都存储在堆中。
4.2堆的特点:
1、线程共享:
整个java虚拟机只有一个堆,所有线程都访问同一个堆。而程序计数器,java虚拟机栈,本地方法栈都是一个线程对应一个。
2、虚拟机启动时创建
3、垃圾回收的主要场所
4、可以进一步细分为新生代,老年代(这个记得JDK7之后与之前有所改动)。新生代又可以分为Eden(伊甸,起点的意思?)、from servior、to servior。不同的区域存放不同周期的对象。虚拟机根据不同的区域采取不同的垃圾回收算法,从而更高效。
5、主流虚拟机堆都是可扩展的,当线程请求虚拟机分配内存,但堆已满的时候,会抛出outofmemoryError
5.方法区
5.1、什么是方法区:
java虚拟机规范中定义方法区是堆的一个逻辑部分。
方法区中存放被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。
5.2、方法区的特点:
1、线程共享:由于是堆的一部分,所以和堆一样都是线程共享的,整个虚拟机都只有一个方法区。
2、永久代:方法区中的数据一般要长期存在,而且它又是堆的逻辑分区,所以按照堆的划分方法,我们把方法区称为老年代。
3、方法去中的数据一般长期存在,垃圾回收器一次只能回收少量数据,所以垃圾回收策略主要是对常量池的回收以及类型的卸载。
4、java虚拟机规范对方法区要求比较宽松,允许固定或扩展大小,也允许不执行垃圾回收。
5.3、运行时常量池
方法区中存放三种数据:类信息、常量、静态变量、即时编译器编译后的代码(这是啥)。其中常量存储在运行时常量池中。
我们一般在一个类中通过public static final来声明一个常量。这个类被编译后便生成Class文件,这个类的所有信息都存储在这个class文件中。
当这个类被Java虚拟机加载后,class文件中的常量就存放在方法区的运行时常量池中。而且在运行期间,可以向常量池中添加新的常量。如:String类的intern()方法就能在运行期间向常量池中添加字符串常量。
当运行时常量池中的某些常量没有被对象引用,同时也没有被变量引用,那么就需要垃圾收集器回收。
6. 直接内存
直接内存是除Java虚拟机之外的内存,但也有可能被Java使用。
在NIO中引入了一种基于通道和缓冲的IO方式(看不懂)。它可以通过调用本地方法直接分配Java虚拟机之外的内存,然后通过一个存储在Java堆中的DirectByteBuffer对象直接操作该内存,而无需先将外面内存中的数据复制到堆中再操作,从而提升了数据操作的效率。
直接内存的大小不受Java虚拟机控制,但既然是内存,当内存不足时就会抛出OOM异常。
创建对象过程与访问对象的过程
创建对象的过程:https://blog.csdn.net/u010425776/article/details/51190801
摘抄对象内存模型:
对象的创建过程
当虚拟机遇到一条含有new的指令时,会进行一系列对象创建的操作:
检查常量池中是否有即将要创建的这个对象所属的类的符号引用;
- 若常量池中没有这个类的符号引用,说明这个类还没有被定义!抛出ClassNotFoundException;
- 若常量池中有这个类的符号引用,则进行下一步工作;
进而检查这个符号引用所代表的类是否已经被JVM加载;
- 若该类还没有被加载,就找该类的class文件,并加载进方法区;
- 若该类已经被JVM加载,则准备为对象分配内存;
根据方法区中该类的信息确定该类所需的内存大小;
一个对象所需的内存大小是在这个对象所属类被定义完就能确定的!且一个类所生产的所有对象的内存大小是一样的!JVM在一个类被加载进方法区的时候就知道该类生产的每一个对象所需要的内存大小。从堆中划分一块对应大小的内存空间给新的对象;
分配堆中内存有两种方式:- 指针碰撞
如果JVM的垃圾收集器采用复制算法或标记-整理算法,那么堆中空闲内存是完整的区域,并且空闲内存和已使用内存之间由一个指针标记。那么当为一个对象分配内存时,只需移动指针即可。因此,这种在完整空闲区域上通过移动指针来分配内存的方式就叫做“指针碰撞”。 - 空闲列表
如果JVM的垃圾收集器采用标记-清除算法,那么堆中空闲区域和已使用区域交错,因此需要用一张“空闲列表”来记录堆中哪些区域是空闲区域,从而在创建对象的时候根据这张“空闲列表”找到空闲区域,并分配内存。
综上所述:JVM究竟采用哪种内存分配方法,取决于它使用了何种垃圾收集器。
- 指针碰撞
为对象中的成员变量赋上初始值(默认初始化);
设置对象头中的信息;
调用对象的构造函数进行初始化
此时,整个对象的创建过程就完成了。
访问对象的过程
我们知道,引用类型的变量中存放的是一个地址,那么根据地址类型的不同,对象有不同的访问方式:
句柄访问方式
堆中需要有一块叫做“句柄池”的内存空间,用于存放所有对象的地址和所有对象所属类的类信息。
引用类型的变量存放的是该对象在句柄池中的地址。访问对象时,首先需要通过引用类型的变量找到该对象的句柄,然后根据句柄中对象的地址再访问对象。直接指针访问方式
引用类型的变量直接存放对象的地址,从而不需要句柄池,通过引用能够直接访问对象。
但对象所在的内存空间中需要额外的策略存储对象所属的类信息的地址。
【JVM】01虚拟机内存模型的更多相关文章
- java中JVM虚拟机内存模型详细说明
java中JVM虚拟机内存模型详细说明 2012-12-12 18:36:03| 分类: JAVA | 标签:java jvm 堆内存 虚拟机 |举报|字号 订阅 JVM的内部结构 ...
- JVM学习笔记——内存模型篇
JVM学习笔记--内存模型篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存模型部分 我们会分为以下几部分进行介绍: 内存模型 乐观锁与悲观锁 synchronized优化 内 ...
- Java虚拟机内存模型及垃圾回收监控调优
Java虚拟机内存模型及垃圾回收监控调优 如果你想理解Java垃圾回收如果工作,那么理解JVM的内存模型就显的非常重要.今天我们就来看看JVM内存的各不同部分及如果监控和实现垃圾回收调优. JVM内存 ...
- 【JVM】Java内存模型
原文:多线程之Java内存模型(JMM)(一) 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标之一.一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per S ...
- [转帖]JVM—深入理解内存模型与垃圾收集机制
JVM—深入理解内存模型与垃圾收集机制 https://juejin.im/post/5d68dc9ee51d4561ad6548f7 前言 Java是一种跨平台的语言,当初其设计初衷也是为了解决各个 ...
- (转载)JVM中的内存模型与垃圾回收
转载自微信公众号:Java高级架构(Java-jiagou)-----看完这篇文章,我奶奶都知道JVM中的内存模型与垃圾回收了! 六.内存模型 6.1 内存模型与运行时数据区 Java虚拟机在执行J ...
- 栈帧 2.6. Frames 虚拟机内存模型
https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-2.html#jvms-2.6 小结: 1. https://docs.oracle. ...
- Java虚拟机--内存模型与线程
Java虚拟机--内存模型与线程 高速缓存:处理器要与内存交互,如读取.存储运算结果,而计算机的存储设备和处理器的运算速度差异巨大,所以加入一层读写速度和处理器接近的高速缓存来作为内存和处理器之间的缓 ...
- jvm 虚拟机内存模型
来源:https://blog.csdn.net/A_zhenzhen/article/details/77917991?locationNum=8&fps=1 https://blog ...
随机推荐
- https学习笔记
HTTPS协议 HTTPS可以认为是HTTP + TLS.HTTP协议大家耳熟能详了,目前大部分WEB应用和网站都是使用HTTP协议传输的.TLS是传输层加密协议,它的前身是SSL协议,最早由nets ...
- Gradle Android它自己的编译脚本教程的最新举措(提供demo源代码)
一.前言 Gradle 是以 Groovy 语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自己主动化构建工具. 上面这句话我认为写得非常官方,大家仅仅需知道Gradle能够用来an ...
- C++使用Windows API CreateMutex函数多线程编程
C++中也可以使用Windows 系统中对应的API函数进行多线程编程.使用CreateThread函数创建线程,并且可以通过CreateMutex创建一个互斥量实现线程间数据的同步: #includ ...
- 使用xtrabackup实现MySQL主从复制
环境描写叙述 主从环境 项目 Master Slave OS版本号 SuSE 11sp1 x86_64 SuSE 11sp1 x86_64 MySQL版本号 官方版本号5.5.37 官方版本号5.5. ...
- Win10局域网内无法共享的解决方法分享(开启Server和ComputerBrowser服务,其它文章也不错)
局域网共享是办公环境下经常使用的,而有些用户反应在升级到win10系统后,网络总是无法共享,给用户带来了很大的困扰,如果你也遇上这样的情况,并通过一些方法无较后,不妨尝试下小编提供的方法. 如果在Wi ...
- 神户制钢坑了500家企业 百年老店为何走上邪路?(企业经营再艰难,也不能降低产品质量,甚至偷工减料,同样适用于IT行业)
神户制钢这颗烂萝卜,拔出它之后带出的泥越来越多.上周五社长川崎博也又开了记者会,再次道歉,而受到其数据造假影响的客户数量也从200家飙升到500家. 日本政府给神户制钢两周时间调查,还要在一个月内公布 ...
- SEO分享:为什么我的资源外链这么多的高品质?
在小浪前制成的制品" [完整版]我怎么3的月800单词索引厨师主页!".之后,很多人都表示了极大的钦佩观看.顽强的运行力,真SEO它是运行顽强的力量.也有人说是吹牛吧,一天500外 ...
- windows安装Oracle10G
1.解压文件10201_database_win32.zip.并双击解压文件夹下的setup.exe,出现安装界面,例如以下: 输入口令和确认口令.如:password,点击下一步,出现例如以下 ...
- HTTP协议知识点 (11个知识点,比较详细)
(一) 对象更新校验方式: HTTP通过两种方式验证对象是否有更新if-non-match 或者 if-modified-since. 通过在Request中包含上述header向服务器发起询问. ...
- JAVASCRIPT高程笔记-------第 七章 函数表达式
7.1递归 经典递归例子 function factorial(num){ if(num <= 1){ return 1; }else{ return num * factorial(num - ...