首页 > 其他分享 >04_Jvm

04_Jvm

时间:2023-07-06 10:34:28浏览次数:27  
标签:04 对象 虚拟机 算法 线程 内存 Jvm 方法

JVM

什么是JVM

java虚拟机,我们所写的代码就是在jvm上运行,我们平时书写的代码是.java文件,然后经过编译为.class字节码文件,现在我们想要运行它,首先需要启动JVM虚拟机,JVM虚拟机本身也是一个程序(用C书写的)

JVM由哪几部分组成

类加载器

我们经过编译后的字节码文件还是存放在磁盘的一个个文件,类加载器帮我们将一个个字节码文件加载到虚拟机的内存中

运行时数据区

JVM在运行时所管理的内存区域,我们把它叫做运行时数据区,它划分了几个部分,分别存储不同的数据

执行引擎

会将java字节码指令翻译成计算机所识别的指令,然后交给CPU去执行,这也是java实现跨平台的原因,不管什么系统jvm都会翻译为对应计算机所识别的指令,交给CPU去执行。

本地方法接口

由native修饰的方法,没有方法的实现,它是由其他语言实现的,所以这些方法就需要本地方法接口来调用,也叫JNI

运行时数据区

  1. 方法区(jdk1.7之前也被称为永久代,jdk1.8也被称为元数据空间。),存的是一些字节码对象,类的信息,或者是一些常量信息,还有一些static修饰的静态信息,这些信息存活的时间普遍比较长。也能进行垃圾回收,回收效果不是特别好,
  2. 堆:对象new出来时,会被放到堆中,是5块区域里最大的一块区域,java中,几乎所有的对象都是存储在堆当中的,它是垃圾回收的一个主要的区域
  3. Java虚拟机栈,存放的是方法相关的数据,栈是先 进后出,我们在运行一个方法的时候,等于就启动了一个线程,此时,就会拥有它的虚拟机栈,和这个方法相关的数据,就会被封装成一个对象,当我们执行某个方法的时候,jvm把这个方法封装成一个栈针入栈, 栈针里面有局部变量表,这个局部变量表里面就是这个方法有哪些局部变量地址,同时,方法的入口,方法的出口,操作的内容,都会存放在这个栈针里,一个方法执行完毕,栈针就会移除出栈,递归运行方法,可能会导致栈溢出异常,当然,这个栈的大小也是可以调整的。 JVM参数 -Xss128k
  4. 本地方法栈:刚刚Java虚拟机栈是为Java方法所服务的,本地方法栈是为Native修饰过的方法所服务的
  5. 程序计数器:在任何一个时刻,一个内核只能执行一条线程中的指令,程序计数器是为了切换线程后能恢复到正确的执行位置,每条线程都一个独立的程序计数器,如果线程正在执行的方法是Java方法,计数器记录的是虚拟机字节码的指令地址,如果Native方法,计数器为空,这一块区域绝对没有内存溢出的风险

线程共享的区域

  • 方法区

只要jvm已启动,这2个区域就存在了,所有其他的线程都能访问这2个区域的数据

线程私有的区域

  • Java虚拟机栈
  • 本地方法栈
  • 程序计数器

只要创建了一个线程,就会划分出这3个区域,这些线程都可以访问方法区和堆的数据

垃圾回收

什么样的对象为垃圾

可达性分析算法,通过GC Roots的对象作为起点,从这些节点开始向后搜索,搜索走过的路径成为引用链,当一个对象到GC Roots没有任何引用链相连时,则此对象是不可达的,会判断为可回收的对象,如下,可作为GC Roots节点的对象

  • 虚拟机栈中(栈针中的本地变量表)引用的对象,通俗的来讲就是正在执行的方法中的变量所引用的对象
  • 方法区中静态变量所引用的对象
  • 方法区的常量所引用的对象
  • 本地方法栈中所引用的对象

垃圾回收算法

标记-清除算法

最基础的收集算法,过程中分为标记和清除2个阶段,首先标记出需要回收的对象,之后由虚拟机统一回收已标记的对象。这种算法有以下2点不足:

  1. 效率问题,标记和清除的效率都不高
  2. 空间问题,对象被回收之后会产生大量不连续的内存碎片,当需要分配较大对象时,由于找不到合适的空闲内存而不得不再次触发垃圾回收动作
复制算法

将内存划分为大小相同的2部分,每次只使用其中一半,当第一块内存用完了,就把存活的对象复制到另一块内存上,然后清除剩余可回收的对象,这样就解决了内存碎片问题。简单高效。但它的缺点很明显:

  1. 它浪费了一半的内存空间
  2. 如果对象的存活率很高,假设100%存活,那么我们需要将所有对象都复制一遍,并将所有引用地址重置一遍。复制这一工作所花费的时间也比较长。
标记整理算法

2个阶段:

  • 标记:它和标记-清除算法是一模一样的,均是遍历GC Roots,然后将存活的对象标记。
  • 整理:移动所有存活的对象,且按照内存地址依次排列,然后将末端内存地址以后的内存全部回收。

不难看出,标记-整理算法不仅可以弥补标记-清除算法当中,内存区域分散的缺点,也消除了复制算法当中,内存减半的高额代价,可谓是一举2得

分代收集算法

把堆分成新生代和老年代2块区域,每次新创建的对象,会进入新生代,并且有一个GC 年龄,新生代的对象存活率比较低,采用的是复制算法,新生代中又划分为3个区域,最大的Eden区,还有2块幸存者区域,Eden区经过垃圾回收,如果还存活的对象,会进入到幸存者区域,并且GC 年龄 + 1,然后第2次垃圾回收,Eden区,和刚刚的幸存者区都会进行,把存活的对象复制到另一块幸存者区域中。进入到老年代中的对象有以下3个途径,老年代使用的垃圾收集算法是标记-清除 加 标记整理

  1. 在新生代3个区域,反复收集,GC 年龄到达15之后,还存活,直接进入
  2. 占用较大的对象,如果幸存者区域放置不下,会进入老年代
  3. 可以配置参数,超过这个参数大小的对象会进入老年代

标签:04,对象,虚拟机,算法,线程,内存,Jvm,方法
From: https://www.cnblogs.com/xulinjun/p/17531425.html

相关文章

  • 04_idea新建空的工程集成模块
    工程管理模块,模块管理包,包管理类,不要在普通的Java工程下面新建模块,要在空的工程下面新建模块一个工程可以有多个模块,每个模块是你每天的练习代码,复习方便1、新建一个空的项目2、左侧选择空项目菜单3、填写项目名称,项目的存放位置,点击完成4、可以,空的工程没有src目录5、......
  • 04_类加载
    类加载什么时候需要进行类加载new、putstatic、getstatic、invokestatic字节码指令时,如果尚未初始化,则需要先触发初始化对类进行反射调用时初始化一个类时,如果父类尚未初始化虚拟机启动时,用于需要指定一个包含main()方法的主类,虚拟机会先初始化这个主类加载类的过程加载......
  • 【2023-07-04】就睡酒店
    20:00我在生活中,永远是追求宁静的工作和简单的家庭生活。为了实现这个理想,我一直竭力保持宁静的环境,以免受人事的侵扰和盛名的喧嚣。                                            ......
  • AtCoder Beginner Contest 304
    A:1#include<cstdio>2#include<cstring>3#include<algorithm>4#include<iostream>5#include<string>6#include<vector>7#include<stack>8#include<bitset>9#include<cstdlib>10#include......
  • 04_MyBatis03
    1.动态SQL问题之前我们在查询用户信息的时候,可以设置根据不同的条件查询用户信息,具体代码如下:可以根据用户id查询用户的信息Mapper接口publicList<User>queryUserById(Integerid);Mapper.xml<selectid="queryUserById"resultType="user"> select*fromuserwhere......
  • 5分钟学会img标签加载图片404错误解决方案
      在开发中,使用<imgsrc="/img/yys.png"/>加载图片时,会有404错误,也就是图片未找到问题。  现将解决办法 总结如下:  当图片未找到或者404时,就会触发<img/>标签的 onerror属性显示其中的图片。1、直接拼写路径方式:<imgsrc="img/yys.png"onerror="javascript......
  • ASP.NET MVC PUT DELETE 404 C# mvc delete put 失败
    对于使用Url路由访问页面的ASP.NET应用程序,IIS可能会显示404,403之类的错误代码,而且排除了代码问题(本地运行正常),那么就可以加下面这句话:<system.webServer><modules><removename="UrlRoutingModule-4.0"/><addname="UrlRoutingModule-4.0"type="......
  • 04vgg剪枝
    数据集介绍Cifar10数据集是经典的图像分类数据。首先下载数据并制作成Dataset和DataLoaderDataset:Dataset是一个抽象类,它定义了数据的存储和访问方法。它的主要任务是加载和预处理数据。用户可以从此类派生出自定义的数据集类,以处理特定类型的数据(如图像、文本等)。DataLoader:D......
  • ubuntu20.04 卸载已有的显卡驱动,安装安装 NVIDIA 驱动程序 525.85.12(主要是搭建deepst
    nvidia安装deepstream官网:  https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_Quickstart.html一、首先卸载本机的显卡驱动:参考连接(https://blog.csdn.net/gongdiwudu/article/details/128850792)1、卸载驱动库sudoapt-get--purgeremovenvidia*sudoapt......
  • 2023-06-04-Generating-Function-Editor
    You'regrowingdesperatefromthefight.基本策略已知系数的幂级数首先是一些可以通过整体法得到封闭形式的幂级数,所谓整体法,即是通过将幂级数位移,用自己表示自己然后做差。\[\begin{aligned}\left\langle1,1,1,1,1,\dots\right\rangle&\rightarrow\frac{1}{1......