【JVM】JVM内存模型(详细)

这篇具有很好参考价值的文章主要介绍了【JVM】JVM内存模型(详细)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.JVM概述

1.jvm简介

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

2.jvm作用

Java中的所有类,必须被装载到JVM中才能运行,这个装载工作是由jvm中的类装载器完成的,.class这个类型可以在虚拟机运行,但不是直接和操作系统交互,需要jvm解释给操作系统,解释的时候需要java类库,这样就能和操作系统交互。

3.jvm的内存模型

【JVM】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):由开发人员自己定义。

【JVM】JVM内存模型(详细)
【JVM】JVM内存模型(详细)

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部署太多应用。内存满了就oom
			jdk1.6之前:永久代,常量池是在方法区
			jdk1.7去永久代,常量池在堆中
			jdk1.8之后:无永久代,常量池在元空间中

【JVM】JVM内存模型(详细)

3.栈(虚拟机栈-线程隔离)

概念:又名堆栈,主管程序运行,生命周期和线程同步,线程结束,栈内存就释放了。不存在垃圾回收问题。

虚拟机栈储存的是:8大基本类型 + 对象引用 + 实例方法

栈的具体示意图
【JVM】JVM内存模型(详细)

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内存模型(详细)
【JVM】JVM内存模型(详细)

②全局配置

【JVM】JVM内存模型(详细)文章来源地址https://www.toymoban.com/news/detail-401461.html

另一篇:垃圾回收机制详细讲解

到了这里,关于【JVM】JVM内存模型(详细)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [JVM] 2. 类加载子系统(1)-- 内存结构、类加载子系统概述

    类加载子系统的职责是:加载class文件到内存中。 完整的内存结构如下: 类加载过程总体分为Loading(加载)、Linking(链接)、Initialization(初始化)三个环节,在Linking阶段又细分为Verification(验证)、Preparation(准备)、Resolution(解析)三个环节。 通过一个类的全限定名获

    2024年02月16日
    浏览(31)
  • JVM原理:JVM运行时内存模型(通俗易懂)

    做了几年开发,平时除了写代码造BUG和修复BUG之外,偶尔也会遇到反馈说程序较慢问题,要对程序性能排查与优化就得更深入学习,学习JVM可以帮助我们加深对JAVA的理解,让我们具备一定的性能排查与调优的能力,无非就是让程序别太卡或者别挂了,那挂了目前我遇到的主要

    2024年02月08日
    浏览(38)
  • 认识JVM的内存模型

    从上一节了解到整个JVM大的内存区域,分为线程共享的heap(堆),MethodArea(方法区),和线程独享的 The pc Register(程序计数器)、Java Virtual Machine Stacks(Java虚拟机栈)、Native Method Stacks(本地方法栈),如下图 同时也大概了解到各个内存区域主要存储的数据类型,根据之前

    2024年02月10日
    浏览(27)
  • JVM——内存模型

      这里与局部变量自增不同,局部变量调用iinc是在局部变量表槽位上进行自增。  静态变量是在操作数栈自增。 这里的主内存和工作内存时再JMM里的说法。  因为操作系统是时间片切换的多个线程轮流使用CPU. JMM中通过synchronized(同步)保证原子性。 使用synchronized减i+

    2024年02月11日
    浏览(20)
  • JVM五大内存模型

    JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一个虚构出来的计算机,有着自己完善的硬件架构,如处理器、堆栈等。 Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码( 字节码 ),就可以在多种平台上不加

    2024年02月15日
    浏览(29)
  • JVM内存模型深度解读

            JVM(Java Virtual Machine,Java虚拟机)对于Java开发者和运行 Java 应用程序而言至关重要。其重要性主要体现在跨平台性、内存管理和垃圾回收、性能优化、安全性和稳定性、故障排查与性能调优等方面。今天就下学习一下 JVM 的内存模型。         JVM 内存模型(

    2024年03月19日
    浏览(37)
  • 四、JVM-对象内存模型

    一个Java对象在内存中包括3个部分:对象头、实例数据和对齐填充 数据 内存 – CPU 寄存器 -127 补码 10000001 - 11111111 32位的处理器 一次能够去处理32个二进制位 4字节的数据 64位操作系统 8字节 2的64次方的寻址空间 指针压缩技术 JDK1.6出现的 开启了指针压缩 什么时候指针压缩会

    2024年02月14日
    浏览(22)
  • JVM之内存模型

    首先说明下 JVM内存模型 和 Java内存模型 这是两个不同的概念,不要搞混淆了。 JVM内存模型定义了Java程序在运行时如何分配、使用和释放内存,跟存储和执行相关,也就是常说的运行时数据区域。 Java内存模型(Java Memory Model,简称 JMM)是一种规范,定义了线程和主内存之间

    2024年02月08日
    浏览(23)
  • JVM内存模型详解

    JVM内存模型和Java内存模型都是面试的热点问题,名字看感觉都差不多,实际上他们之间差别还是挺大的。     通俗点说,JVM内存结构是与JVM的内部存储结构相关,而Java内存模型是与多线程编程相关@mikechen。   什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一个虚

    2023年04月13日
    浏览(51)
  • JVM学习05:内存模型

    很多人将 java 内存结构 与 java 内存模型 傻傻分不清,java 内存模型是 **Java Memory Model(JMM)**的意思。 JMM 定义了一套在多线程读写共享数据时(成员变量、数组)时,对数据的可见性、有序性、和原子性的规则和保障。 原子性是指一个操作是 不可中断 的。即使在多个线程一

    2024年02月04日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包