【JVM】JVM内存模型(详细)
目录
- 一.JVM概述
- 1.jvm简介
- 2.jvm作用
- 3.jvm的内存模型
- 二.类加载器
- 1.类加载器的作用
- 2.加载器的类型
- 3.双亲委派机制的运行过程
- 4.双亲委派机制优缺点
- 5.为什么要破坏双亲委派机制
- 6.破坏双亲委派机制的方式
- 三.JVM内存模块
- 1.方法区(线程共享)
- 2.堆(线程共享)
- 3.栈(虚拟机栈-线程隔离)
- 4.栈(本地方法栈-线程隔离)
- 5.程序计数器(线程隔离)
- 6.OutOfMemoryError内存溢出和StackOverFlowError栈溢出及解决方法
- (1) OutOfMemoryError内存溢出(OOM)
- (2) StackOverFlowError栈溢出
- (3) idea配置jvm
- 另一篇:垃圾回收机制详细讲解
一.JVM概述
1.jvm简介
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
2.jvm作用
Java中的所有类,必须被装载到JVM中才能运行,这个装载工作是由jvm中的类装载器完成的,.class这个类型可以在虚拟机运行,但不是直接和操作系统交互,需要jvm解释给操作系统,解释的时候需要java类库,这样就能和操作系统交互。
3.jvm的内存模型
二.类加载器
1.类加载器的作用
将class字节码内容加载到内存中,并将这些静态数据转换成方法区运行时数据结构,然后在堆中形成代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口。类装载器所做的工作实质是把类文件从硬盘读取到内存中。
2.加载器的类型
引导类加载器(Bootstrap ClassLoader)
:用c++编写,是JVM自带的类加载器,负责java平台核心库,用来装载核心类库,该加载器无法直接获取。
拓展类加载器(Extension ClassLoader)
:负责jre/lib/ext目录下的jar包或 -D java.ext.dirs 指定下的jar包装入工作库。
系统类加载器(Application ClassLoader)
:负责java-classpath或者 -D java.class.path所指的目录下的类与jar包装入工作,是最常用的加载器。
自定义类加载器(Custom ClassLoader)
:由开发人员自己定义。
3.双亲委派机制的运行过程
① 类加载器收到类加载的请求。
② 将这个请求委托给父类加载器去完成,一直向上委托,直到引导类加载器。
③ 引导类加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则,抛出异常,通知子加载器进行加载,向下加载。
④ 重复步骤③。
4.双亲委派机制优缺点
优点: 保证类加载的安全性,不管那个类被加载,都会被委托给引导类加载器,只有类加载器不能加载,才会让子加载器加载,这样保证最后得到的对象都是同样的一个。
缺点: 子加载器可以使用父加载器加载的类,而父加载器不能使用子加载器加载的类。
5.为什么要破坏双亲委派机制
原因: 子加载器可以使用父加载器加载的类,而父加载器不能使用子加载器加载的类。
举例: 使用JDBC连接数据库,需要用到 com.mysql.jdbc.Driver和DriverManager类。然而DriverManager被引导类加载器所加载,而com.mysql.jdbc.Driver被当前调用者的加载器加载,使用引导类加载器加载不到,所以要打破双亲委派机制。
6.破坏双亲委派机制的方式
(1) 自定义类加载器,重写loadclss()方法。
(2) 使用线程上下文类(ServiceLoader:使父加载器可以加载子加载器的类)。
三.JVM内存模块
1.方法区(线程共享)
方法区存储的是:常量池、静态变量(static)以及方法信息(修饰符、方法名、返回值、参数等)、类信息(类变量)等
2.堆(线程共享)
概念:堆是线程共享的内存区域,它是虚拟机管理内存中最大的一块。
堆储存的是:实例对象。
比如 A a1 = new A();a1就是实例对象。A a2;a2就是类对象。
堆的具体示意图(jdk8及之后)
GC主要在新生区(伊甸园区)、老年区新生区(伊甸园区(对象都是在这个区new出来的)、幸存区to、幸存区from:幸存区位置会互相交换,谁空谁是to)老年区永久区:存储的是java的运行环境或类信息,这个区域不存在垃圾回收,关闭jvm就会释放内存一个启动类加载大量的jar包。tomcat部署太多应用。内存满了就oomjdk1.6之前:永久代,常量池是在方法区jdk1.7去永久代,常量池在堆中jdk1.8之后:无永久代,常量池在元空间中
3.栈(虚拟机栈-线程隔离)
概念:又名堆栈,主管程序运行,生命周期和线程同步,线程结束,栈内存就释放了。不存在垃圾回收问题。
虚拟机栈储存的是:8大基本类型 + 对象引用 + 实例方法
栈的具体示意图
4.栈(本地方法栈-线程隔离)
本地方法栈储存的是:本地接口库里调用的方法,就是java里面
native
关键字修饰的方法。
凡是带native关键字的,说明java的作用范围达不到了,回去调用底层c/c++语言的库,首先会进入本地方法栈,然后到本地方法接口。
5.程序计数器(线程隔离)
每个线程启动是都会创建一个程序计数器,保存的是正在执行的jvm指令,程序计数器总是指向下一条将被执行指令的地址。生命周期与线程的生命周期保持一致。
6.OutOfMemoryError内存溢出和StackOverFlowError栈溢出及解决方法
不论是内存溢出还是栈溢出,简单来说就是你放的太多了空间不够了,溢出来了,这样就比较好理解了。
(1) OutOfMemoryError内存溢出(OOM)
原因:①是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于能提供的最大内存。
②由于长期保持某些资源的引用,垃圾回收器无法回收它,从而使该资源不能够及时释放,也称为内存泄露。
解决:①设置JVM的堆参数( -Xmx:JVM最大内存 -Xms:启动初始内存 -Xmn:新生代大小 -Xss:每个线程虚拟机栈及堆栈的大小 ) 例如:
-Xms1024m -Xmx1024m -Xmn512m -Xss5m
。
②分析内存,看一下那个地方出现了问题(专业工具:Jprofiler,MAT)分析Dump内存文件, 快速定位内存泄漏,怎么查找dump文件,直接找到文件的文件夹打开获得大的对象。
制造堆溢出:一直死循环new对象就ok了。
- –Xms:JVM初始分配的堆内存,默认是物理内存的1/64。
- –Xmx:JVM最大允许分配的堆内存,默认是物理内存的1/4。
- –Xmn:堆内新生代的大小。通过这个值也可以得到老生代的大小:-Xmx减去-Xmn。
- –Xss:规定了每个线程虚拟机栈及堆栈的大小,一般情况下,256k是足够的,此配置将会影响此进程中并发线程数的大小。
- 更多JVM调优总结及命令
(2) StackOverFlowError栈溢出
原因:线程请求分配的栈容量超过Java虚拟机栈允许的最大容量。
解决:①修改代码 ②增加线程堆栈大小(-Xss)。
制造栈溢出:一直死循环调用方法就行。
(3) idea配置jvm
①配置某个项目
②全局配置
另一篇:垃圾回收机制详细讲解
【JVM】JVM内存模型(详细)相关推荐
- java中的vm自变量_java中JVM虚拟机内存模型详细说明
java中JVM虚拟机内存模型详细说明 JVM的内部结构如下图: 一个优秀Java程序员,必须了解Java内存模型.GC工作原理,以及如何优化GC的性能.与GC进行有限的交互,有一些应用程序对性能要求 ...
- 无法装载这个对象_面试官:别的我不管,这个JVM虚拟机内存模型你必须知道
前言 说jvm的内存模型前先了解一下物理计算机的内存处理. 物理计算器上用户磁盘和cpu的交互,由于cpu读写速度速度远远大于磁盘的读写速度速度,所以有了内存(高速缓存区).但是随着cpu的发展,内存 ...
- java jvm内存模型_Java(JVM)内存模型– Java中的内存管理
java jvm内存模型 Understanding JVM Memory Model, Java Memory Management are very important if you want t ...
- JVM 的内存模型及jstat命令的使用
目录 JVM的内存模型 jdk1.7的内存模型 jdk1.8的内存模型 为什么要废弃1.7中的永久代? 通过jstat命令查看堆内存使用情况 查看class加载统计 查看编译统计 垃圾回收统计 JVM ...
- JVM 的内存模型及对象的内存布局(一图尽收眼底)
JVM 的内存模型 Java 数据类型对象的内存布局 2.1 Example layout of a java.lang.Integer object for a 32-bit Java proces ...
- modeler java堆空间,JVM|02内存模型
JVM内存模型 概述 Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保 ...
- JVM——Java内存模型(JMM)
关注微信公众号:CodingTechWork,一起学习进步. 软硬件发展概述 Amdahl定律和摩尔定律 1)Amdahl定律:通过系统中并行化和串行化的比重来描述多处理器系统能获得的运算加速能力. ...
- JVM对象内存分配详细过程(栈上分配->TLAB->老年代->Eden区)
一个类创建实例的时候,需要经过多个步骤,比如我们调用new的时候经过了哪些流程,本文就来详细分析下 专业术语 逃逸分析算法 逃逸分析其实就是分析java对象的动态作用域, 如果一个对象被定义之后,被外 ...
- Java内存结构(JVM)与内存模型(JMM)
JVM内存结构 我们都知道,Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途.其中有些区域随着虚拟机进程的启动而存 ...
最新文章
- 数学之美 系列八-- 贾里尼克的故事和现代语言处理
- 数据结构与算法之反转单向链表和双向链表
- Android动态权限申请工具类非常好用包含9组危险权限
- 从CNNIC的“中国互联网报告”看到希望
- fread读取整个文件_qt如何实现大文件的加载和显示
- 多元线性回归matlab代码_医学统计|多元线性回归分析
- 计算机网络「二」—— 物理层(多图详解)
- 数据分析与挖掘建模实战002:数据获取
- C#调用Matlab生成的dll方法
- Cimag 用法总结
- ubuntu开机自启动python程序
- 微信查询对账单对账+数据读取解析入库
- 四面阿里软件测试被刷,怒刷三个月测试面试题,成功进入哔哩哔哩
- 苹果无线耳机连接不上_为什么我们一定要买TWS真无线耳机?
- Photoshop脚本 压缩并输出GIF图片
- storyboard 苹果启动图_iOS13 启动图适配
- 浅谈超融合一体机-即买即用的企业级私有云
- Octave简明教程
- Velocity模板语言(VTL):说明
- Linux下Nuke 12.2.v5 安装及使用
热门文章
- TeamViewer被检测为商用
- win32api之链接库的创建与调用(八)
- HDU 1009 FatMouse' Trade(简单贪心 物品可分割的背包问题)
- 汇编语言王爽-实验9
- 包嗅探和包回放简介-tcpdump,tcpreplay
- wintogo论坛_新一代垃圾佬的大辅助装-WIN TO GO
- CISP——访问控制(自主访问控制和强制访问控制)
- 如何查看Win11可以升级22h2?Win11升级22h2的方法
- 【学习】从零开发的Android音视频开发(13)——MediaCodec到OMX框架过程及其硬解码
- Google的OR-Tools