当前位置: 首页 > news >正文

吴忠建设局网站莆田seo

吴忠建设局网站,莆田seo,c#+开发网站开发,自己做网站语言包怎么做目录 前言 JVM简介 JVM内存区域划分 JVM的类加载机制 1.加载 双亲委派模型 2.验证 验证选项 3.准备 4.解析 5.初始化 触发类加载 JVM的垃圾回收策略 GC 一#xff1a;找 谁是垃圾 1.引用计数 2.可达性分析 #xff08;这个方案是Java采取的方案#x…目录 前言 JVM简介 JVM内存区域划分 JVM的类加载机制 1.加载 双亲委派模型 2.验证 验证选项 3.准备 4.解析 5.初始化 触发类加载 JVM的垃圾回收策略 GC 一找     谁是垃圾  1.引用计数 2.可达性分析  这个方案是Java采取的方案。 二释放垃圾对象 三种典型的策略 JVM实现思路 前言 我们在学习JVM的时候其实里面的内容是非常之多的但是里面的大部分内容都是属于八股想要彻底搞明白就需要看大量的关于JVM的源代码JVM的源代码是C写的。想要深入研究的可以去看看《深入理解Java虚拟机》这本书。 这篇文章主要针对JVM中的常见的面试题来展开。 JVM简介 JVM 是 Java Virtual Machine 的简称意为 Java虚拟机。 虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。 常见的虚拟机JVM、VMwave、Virtual Box。 JVM 和其他两个虚拟机的区别 VMwave与VirtualBox是通过软件模拟物理CPU的指令集物理系统中会有很多的寄存器JVM则是通过软件模拟Java字节码的指令集JVM中只是主要保留了PC寄存器其他的寄存器都进行了裁剪。 JVM 是一台被定制过的现实当中不存在的计算机。 JVM内存区域划分 JVM其实就是一个Java进程Java进程也就是JVM会从操作系统这里申请一大块内存空间给Java代码来使用。 JVM从操作系统申请的这块内存空间中进行进一步的划分给出了每块划分后的空间的不同用途。 其中最核心的就是栈、堆、元数据区方法区。 虚拟机栈是给Java代码来使用的主要存放一些局部变量还有维护方法之间的调用关系。本地方法栈则是给JVM内部的本地方法来使用的。堆上存放的就是new出来的对象、成员变量。程序计数器中存放的就是一个内存地址这个内存地址就是下一个要执行字节码所在的地址作用就是记录当前程序执行到那个指令了。 需要注意的是堆和元数据区在一个JVM 中只存在一份也就是多个线程共享堆区和元数据区。 栈(本地方法栈和虚拟机栈)和程序计数器则是存在多份的也就是每个线程都会有一份。 JVM的线程操作和操作系统的线程操作是一对一的关系。也就是说每次在Java代码中创建的线程都会在操作系统中有一个线程与之对应。 这里的面试题主要就是判断某个变量或者对象在JVM的那个区域 例如下面代码 void func() {Test t1 new Test(); } 上述代码在一个方法里面我们实例化了一个Test对象。 func方法是在元数据区以一些二进制的指令来存储的。 我们可以看到t1变量是一个在方法里面定义的所以他是一个局部变量局部变量就存储在栈上。 而new Test(); 这个对象的本体则是在堆上的。 其实像这里的关于JVM区域的面试题我们只需要知道JVM的每个区域都是存储什么东西的就好了。 虚拟机栈是给Java代码来使用的主要存放一些局部变量还有维护方法之间的调用关系。本地方法栈则是给JVM内部的本地方法来使用的。堆上存放的就是new出来的对象、成员变量。程序计数器中存放的就是一个内存地址这个内存地址就是下一个要执行字节码所在的地址作用就是记录当前程序执行到那个指令了。 JVM的类加载机制 对与一个类来说他的生命周期是这样的 前面的5步也是类加载的过程和固定的顺序。我们主要研究前面的5步。 类加载具体就是把一个.class文件也就是类编译后的文件加载到内存中得到了类对象这样的过程就称之为类加载。 一个程序想要运行就需要把指令和数据加载到内存中。类加载就是做的这个事情。 下面是类加载的5个步骤 1.加载 这里的加载过程其实简单就是找到.class文件然后读取文件的内容。 但是在找.class文件的这个过程中会有一个非常重要的机制双亲委派模型 双亲委派模型 在JVM中加载类需要用到一组特殊的模块类加载器。 在JVM中内置了三个类加载器。 BootStrap ClassLoader    负责加载Java标准库中的类Extension ClassLoader     负责加载一些非标准的但是是Sun/Oracle扩展库的类Application ClassLoader    负责加载项目中自己写的类、以及第三方库中的类 当具体加载一个类的时候他的过程是这样的 需要先给定一个类的全限定类名java.lang.String  这个类名是一个字符串的形式。 如果一个类加载器收到了类加载的请求它首先不会自己去尝试加载这个类而是把这个请求委派给父类加载器去完成每一个层次的类加载器都是如此因此所有的加载请求最终都应该传送到最顶层BootStrap ClassLoader类加载器中只有当父加载器反馈自己无法完成这个加载请求它的搜索范围中没有找到所需的类时子加载器才会尝试自己去完成加载。 具体可以参考下图 2.验证 由于.class文件有着明确的数据格式二进制的这一阶段的主要目的就是确保Class文件中的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求。 验证选项 文件格式验证 字节码验证 符号引用验证…… 3.准备 准备阶段是正式为类中定义的变量即静态变量被static修饰的变量分配内存并设置类变量初始值的阶段。 比如下面这样的代码 public static int value 123; 此时在准备阶段value的值并不是123而是0。   4.解析 解析阶段是Java虚拟机将常量池内的符号引用替换为直接引用的过程也就是初始化常量的过程。 符号引用就是字符串常量在.class文件已经存在但是他们只知道彼此之间的相对位置并不知道自己在内存中的具体位置。直接引用真正的加载到内存中就会把字符串常量填充到内存中的特定地址上去。此时字符串引用的就是直接引用也就是Java中普通的引用。 5.初始化 在初始化阶段JVM才真正的执行类中编写的Java代码将主导权交给应用程序初始化阶段就是执行类的构造方法的过程。类要是有父类就需要先初始化父类在初始化子类。 触发类加载 注意类加载这个动作不是说JVM一启动就会进行加载因为JVM整体是一个懒加载的策略也就是非必要不加载。 以下三种请况就会加载 创建了这个类的实例使用了这个类的静态方法/静态属性使用子类会触发父类的加载 JVM的垃圾回收策略 GC Java中的垃圾回收是为了帮助我们自动释放内存的一种机制。 面试题为什么需要垃圾回收机制 因为在程序运行过程中会向操作系统申请大量的内存空间但是这些空间也有可能会消耗尽因为不断地分配内存空间而不进行回收就好像不停地生产生活垃圾而从来不打扫一样。 上面我们谈到了关于JVM的几个区域那么垃圾回收释放的是那个区域的空间呢 需要注意的是栈和程序计数器是每个线程都会有一份的。他们会随着线程的销毁而一起销毁的。 而元数据区里面的存储的类对象很少会进行销毁。 所以我们释放的就是堆中的空间。上面我们谈到堆中主要就是存放new 出来的对象的。 GC也就是以对象为单位进行释放的。释放对象 GC中主要分为两个阶段 一找     谁是垃圾  Java通过引用来判断是否是垃圾对象如果没有引用指向就判定这个对象是垃圾。 1.引用计数 给对象安排一个额外的空间保存了一个整数表示该对象有几个引用指向它。Java实际上并没有采取这样的方案Python、PHP采用了这个方案。 Test t1 new Test();此时是有一个引用指向的所以引用计数器为1。 如果代码变成这样 Test t1 new Test(); Test t2 t1; 也就是说随着引用的增加计数器就会增加引用的销毁计数器就会减少。 当计数器为0时就会认为该对象没有引用指向了就是垃圾了。 但是缺点也是很明显 浪费内存空间存在循坏引用的情况 2.可达性分析  这个方案是Java采取的方案。 把对象之间的引用关系理解成为了一个树形结构从一些特殊的起点出发进行遍历只要能访问到是可达的不是垃圾再把不可达的当做垃圾即可。 此时通过root这个引用是可以访问到整个树的任意节点的。 可达性分析的关键要点在于要进行上述的遍历需要有起点的。 起点可以是 栈上的局部变量每个栈的每个局部变量都是起点常量池中引用的对象方法区中静态成员引用的对象 可达性分析总体就是从所有的起点出发看看该对象里面又通过哪些引用能访问到那些对象顺藤摸瓜的把所有可以访问的对象都访问一遍遍历的同时把对象标记为“可达”。 可达性分析克服了引用计数的两个缺点 但是也是有自己的问题 消耗更多的时间 因此即使某个对象成了垃圾也不能第一时间发现因为在扫描的过程中也是需要时间的。在进行可达性分析的时候要顺藤摸瓜一旦这个过程中当前代码中的对象的引用关系发生了变化就可以出现bug。 因此为了更好的完成这个顺藤摸瓜的过程就需要让其他的业务线程都暂停工作STW (STW)   stop the world ! 但是Java毕竟发展了这么多年拉进回收这里也是在不断的进行优化STW这个问题也可以比较好的对付了。 二释放垃圾对象 三种典型的策略 1标记清除 如果现在向内存申请了一块下面这样的空间然后我标出来的就是垃圾对象需要清除的。 这种策略就是直接把垃圾对象的内存就释放了。 但是这种简单粗暴的方式会产生内存碎片。 内存碎片申请空间都是连续的整块空间现在上述图中的空闲空间都是散落在独立的空间里面的。现在空闲总空间可能超过1G但是我想申请500M却是申请不了。 2复制算法 这种方法是把空间分为两部分。一次只使用一半。 复制算法就是把不是垃圾的对象拷贝到一边去然后在统一释放整个区域。 此时我要释放的是2和4我就需要把剩下1和3复制到另一边去。然后再把这边全部释放。 复制算法解决了内存碎片的问题但是也有缺点 内存利用率比较低如果大部分对象都是保留的垃圾很少此时的复制成本就比较高 3标记整理 类似于顺序表删除中间元素有一个搬运的过程 解决了内存碎片问题但是搬运的整体开销也是比较大的。 JVM实现思路 实际上JVM的实现方式是结合了上述几种思想之后的方法。 分代回收思想 具体细节 给对象设置年龄这样的概念用来描述这个对象存在多久了。如果一个对象刚诞生那么就是0岁。每次进过一次扫描可达性分析如果没有被标记为垃圾对象这是对象年龄就增加一岁。通过年龄来区分这个对象的活动时间。 经验规律年龄越大的对象也将会持续存在更长的时间。 针对不同的年龄来采取不同的回收策略 JVM针对这几个区域来执行不同的策略。 1新创建的对象放在伊甸区 垃圾回收扫描到伊甸区之后大多数的对象将会在第一轮扫描下被GC给淘汰掉。 2如果伊甸区的对象熬过第一轮GC就会通过复制算法拷贝到生存区。 生存区分为两半大小相等一次只使用其中的一半。 如果GC在扫描生存区的时候发现垃圾对象也就淘汰不是垃圾的就通过复制算法拷贝到生存区的另一边。 3当对象在生存区熬过了若干次GC的时候年龄也变大了。此时就会通过复制算法拷贝到老年代。 4进入老年代之后由于年龄都比较大了被标记为垃圾对象的概念也很小所以针对老年代的GC扫描也会降低频率。 特殊情况如果对象非常大直接进入老年代大对象进行复制算法成本非常高而且大对象也不会很多。
http://www.zqtcl.cn/news/276872/

相关文章:

  • 网站维护费用一年多少广州h5网站建设
  • 如何搭建静态网站源码手机开发软件app的工具
  • 之前做的网站推广怎么删除专业做网站官网
  • 泉州做 php 网站宁波信息港
  • 网站建设专员招聘如何建立网站会员系统
  • 佛山网站关键词自助建站教程
  • 海口网站seo做网站域名后缀选择
  • 网站建设新手看什么书网络营销推广师
  • 小浣熊做单网站观看床做视频网站
  • 网站版面布局结构图门户网站要求
  • 网站左侧广告代码网站建设交接协议书
  • dedecms网站上传华为网络营销案例分析
  • wordpress搭建站点龙岗网站建设代理商
  • 做销售网站要多少钱建立网站的流程
  • 视频类网站如何做缓存网页设计框架怎么写
  • wordpress建站访问提示不安全网页加速器哪个最好用
  • 网博士自助建站系统下载毕业设计代做网站唯一
  • 江西网站建设优化服务营销软文范例大全100字
  • 图片类网站怎样做高并发专业做旗袍花的网站是什么网站
  • 我要建网站需要什么专业网站制作全包
  • 网站开发合同印花税自定义手机网站建设
  • 营销型网站开发流程制作网站需要钱吗
  • 提供有经验的网站建设百度识图识别
  • html手机网站怎么做湖南关键词优化品牌推荐
  • 网站定制开发收费标准是多少易语言如何做浏网站
  • 网站怎么做实名认证新手怎么开婚庆公司
  • .net做网站用什么技术网站优化排名方案
  • 电商网站备案流程网站移动端优化的重点有哪些
  • 数据需求 网站建设做qq空间的网站
  • 微信网站游戏网络规划设计师可以挂证吗