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

东莞市卫生健康局seo与网站优化 pdf

东莞市卫生健康局,seo与网站优化 pdf,今天河北沧州确诊名单,做分析图很好用的网站#x1f970;#x1f970;#x1f970;来都来了#xff0c;不妨点个关注叭#xff01; #x1f449;博客主页#xff1a;欢迎各位大佬!#x1f448; 文章目录 1. JVM 中的内存区域划分2. JVM 的类加载机制2.1 加载(Loading)✨双亲委派模型2.2 验证(Verification)2.3 准… 来都来了不妨点个关注叭 博客主页欢迎各位大佬! 文章目录 1. JVM 中的内存区域划分2. JVM 的类加载机制2.1 加载(Loading)✨双亲委派模型2.2 验证(Verification)2.3 准备(Preparation)2.4 解析(Resolution)2.5 初始化(Initialization) 3. JVM 中的垃圾回收3.1 找 —— 谁是垃圾3.1.1 引用计数法3.1.2 可达性分析 3.2 释放 —— 把垃圾对象的内存给释放掉3.2.1 标记清除算法3.2.2 复制算法3.2.3 标记整理算法3.2.4 分代算法 本期内容主要介绍有关 JVM 相关知识这里只是简单介绍JVM 的知识有很多具体可看参考书《深入理解Java虚拟机》作为一名普通的 Java 程序猿日常开发中的时候几乎是涉及不到 JVM 相关内容哒~ JVM 设计的初心就是为了让 Java 程序猿感知不到系统层面的一些内容程序猿只需关注业务逻辑不要关注底层的实现细节!!! JVM 里的内容是非常多的需要研究 JVM 的源代码其源代码由 C 编写本期内容针对以下三个方面进行介绍 JVM我们一起来看看吧~ 1. JVM 中的内存区域划分 JVM 其实是一个 Java 进程Java 进程会从操作系统这里申请一大块内存区域给 Java 代码使用对这块内存区域进一步划分为几个最核心的内存区域给出不同的用途 堆存放 new 出来的对象成员变量栈存放维护方法之间的调用关系也会存一些局部变量方法区/元数据区存放类加载之后的类对象这里的类对象就包含了静态变量 方法区是旧的叫法最新叫法为元数据区 【类对象】 类对象是什么即类加载之后的东西本来一个类是.class 文件把它加载在内存里需要有一个数据结构来表示它可以通过类名.class比如 Test.class 来获取 Test 类对象 这里的主要考点就是给一段代码判断某个变量处于内存的哪个区域~ 【规则】是看这个变量的形态比如是局部变量还是成员变量还是静态变量呢如果是局部变量就存放在栈上如果是成员变量就存放在堆上如果是静态变量就存放在方法区内~ 【注意】和变量的类型是无关的!!! 并不是内置类型变量就在栈上引用类型变量就在堆上 举一个具体的栗子代码如下 // Test类 class Test { }void func() {Test t new Test(); }分析如下t 本身是一个引用类型它是一个局部变量因此存放在栈上而 new 出来的对象对象本身是成员变量存放在堆上 以下是 JVM 的执行流程下面系统重点介绍 JVM 运行时数据区JVM 运行时数据区域也叫内存布局如图 这里需要注意 1堆和方法区在一个 JVM 进程中只有一份但是栈(包括虚拟机栈与本地方法栈)和程序计数器则存在多份每一个线程都有一份 2JVM 的线程和操作系统的线程是一一对应的关系每次在 Java 代码中创建线程必然会在系统中有一个对应的线程 JVM 内存划分区域 本地方法栈是给 JVM 内部的本地方法使用的其中 JVM 内部通过 C 代码实现的方法虚拟机栈是给 Java 代码使用的它的生命周期和线程一样当线程执行一个方法的时候会创建一个对应的栈帧用于存储局部变量等信息然后栈帧被压入栈中当方法执行完毕后栈帧会从栈中移除程序计数器也称 PC 计数器用途是记录当前程序指定到哪个指令了是一个简单的 long 类型的变量存了一个内存地址内存地址就是下一个要执行的字节码所在的地址堆堆是 JVM 中最大的一块内存区域被所有线程共享在 JVM 启动时创建用来存储对象方法区方法区也是所有线程共享的用于存储类加载之后的对象 2. JVM 的类加载机制 【类加载】就是把 .class 文件加载到内存中得到类对象的这样一个过程程序想要运行就需要把依赖的指令和数据加载到内存中 类加载的步骤其实非常复杂本期内容开头提到的书把类加载的过程总结为 5 个词也是 Java 虚拟机规范分为加载 —— 验证 —— 准备 —— 解析 —— 初始化如下图 下面具体介绍这五个步骤 2.1 加载(Loading) 【加载】加载阶段就是找到 .class 文件并且读文件的内容 在加载(Loading)阶段Java虚拟机需要完成以下三件事情 通过类名.class 获取二进制字节流把这个字节流所代表的静态存储结构转化为方法区的运行时数据结构在内存中生成一个代表这个类的 java.lang.Class 对象作为方法区这个类的各种数据的访问入口 【注意】加载是类加载的一个阶段加载是加载类加载是类加载注意区分两者~ 如何找到这个 .class 文件呢这里会涉及到一个经典的考点双亲委派模型 ✨双亲委派模型 在介绍双亲委派模型之前需要先知道 JVM 加载类时需要用到一组特殊的模块 —— 类加载器 类加载器用于动态加载 Java 类到 Java 虚拟机中主要有以下 4 种类型类加载器其中在 JVM 中内置了三个类加载器即如下的前三个 启动类加载器Bootstrap ClassLoader负责加载 Java 标准库中的类扩展类加载器Extension ClassLoader负责加载一些非标准库但是由 Sun / Oracle 扩展的库的类应用程序类加载器Application ClassLoader负责加载项目中自己写的类以及第三方库中的类用户自定义类加载器User-Defined ClassLoader可以通过继承 java.lang。ClassLoader 类来创建自己的类加载器 类加载中最关键的一个考点是双亲委派模型双亲委派模型做的工作就是在类加载的第一个阶段 —— 加载阶段找 .class 文件这个过程 ~ 【双亲委派模型】 这种模型指的是一个类加载器在尝试加载某个类的时候首先会将加载任务委托为其父类加载器去完成只有当父类加载器无法完成这个加载请求即父类加载器找不到指定的类子类加载器才会尝试去自己加载这个类 这里仅考虑在 JVM 中内置的三个类加载器具体流程如下 当一个类加载器需要加载某个类的时候它首先会请求其父类加载器加载这个类Bootstrap ClassLoader 启动类加载器没有父加载器了因此只能自己来搜索自己负责的片区如果搜索到就直接进行后续加载步骤如果没有搜索到再交给孩子处理Extension ClassLoader 扩展类加载器收到了父亲的反馈自己来找如果搜索到就直接进行后续加载步骤如果没有搜索到再交给孩子处理Application ClassLoader 应用程序类加载器收到了父亲的反馈自己来找如果搜索到就直接进行后续加载步骤如果没有搜索到再交给孩子处理但是这里没有孩子了就会抛出一个 ClassNotFoundException 这个流程在日常中也经常存在把 Bootstrap 想象成公司老板Extension 想象成主管Application 想象成基层员工 【双亲委派模型的优点】 避免重复加载类比如 A 类和 B 类都有共同的父类 C 类当 A 启动时就会将 C 类加载起来在 B 类进行加载时就不需要在重复加载 C 类 保证安全性使用双亲委派模型也可以保证 Java 的核心 API 不被篡改 【注意】 1双亲委派模型也是可以打破的比如自己实现的类加载器可以继续遵守双亲委派模型也可以不遵守比如 Tomcat 里针对 webapp 的类加载器就没有遵守双亲委派模型 2反射和类加载的关系是类加载得到的类对象是反射机制的前提条件 2.2 验证(Verification) 【验证】.class 文件有明确的数据格式(二进制)该阶段是确保.class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求保证这些信息被当作代码运行后不会危害虚拟机自身的安全 验证选项有很多比如有 文件格式验证字节码验证符号引用验证… 打开这个官方文档可以查看虚拟机规范 这里找的是 Java SE 8 早一点版本的虚拟机规范在第 4 章可以看到 .class 文件有明确的数据格式如下 2.3 准备(Preparation) 【准备】给类对象分配内存空间未初始化的空间即初始值为数据类型的默认初始值简单认为内存空间中的数据全为 0类对象中的静态成员变量等全为 0 2.4 解析(Resolution) 【解析】针对字符串常量进行初始化即虚拟机将常量池中的符号引用替换为直接引用的过程 解释说明 字符串常量在 .class 文件中就存在了但是它们只是知道彼此之间的相对位置即偏移量并不知道自己在内存中的实际地址此时的字符串常量就是符号引用真正加载到内存中就是把字符串常量填充到内存的特定的地址上字符串常量之间的相对位置还是一样的但是这些字符串常量之间相对位置仍然是一样的但是这些字符串有了真正的内存地址此时的字符串常量就是直接引用了即 Java 中的普通引用 举个例子更能理解 比如小丁和小万是好朋友大课间从教室去操场做操先在教室门口排好队由体育委员带头过去但是走着走着队伍就变形了小丁就需要走位保持和小万是同行的这样小丁和小万一直走在一块相对位置不变到达操场后小丁和小万还是在一块此时两个好朋友就挨着了一起做操了~ 在到达操场前小丁和小万并不知道待会在操场上站在哪里但是两个人的相对距离彼此清楚的真正到达操场后小丁和小万确定了自己的站位位置就固定了此时两个人还是挨着的相对位置不变~ 这就类比符号引用替换为直接引用的过程 2.5 初始化(Initialization) 【初始化】针对类对象进行初始化比如初始化静态成员执行静态代码如果这个类还有父类需要先把父类加载出来 类加载这个动作什么时候会触发呢 并不是 JVM 一启动就把所有的 .class 都加载了坚持着 “非必要不加载” 的原则即需要的时候再加载~ 什么时候是必要 创建了这个类的实例使用了这个类的静态方法/静态属性使用子类会触发父类的加载 3. JVM 中的垃圾回收 【含义】 垃圾回收Garbage CollectionGC从字面上来看就是释放垃圾占用的空间防止内存爆掉JVM 垃圾回收是帮助程序员自动释放掉内存的~ 在 C 语言中malloc 的内存必须手动 free否则就容易出现内存泄露问题即光申请内存不进行释放内存逐渐用完导致程序崩溃Java 等后续的编程语言引入 GC 来解决上述问题能够有效的减少内存泄露的出现概率 【作用】 实际上内存的释放是一个比较纠结的事情 申请的时机是明确的 —— 使用到了就必须申请 释放的时机是模糊的 —— 彻底不使用了才能释放如果还没使用完就释放就会导致一些问题 C/C 的做法是完全让程序员来决定特别依赖程序员的水平Java 通过 JVM 自动判定基于一系列策略就可以提高释放时机的准确性但是同时也会付出一些代价 【JVM 中的垃圾回收的对象】 QJVM 中的内存有好几个区域是释放哪个部分的空间呢 A堆new 出来的对象 程序计数器就是一个单纯存地址的整数不需要释放随着线程一起销毁栈也是随着线程一起销毁方法的局部变量也就自然随着出栈操作销毁了方法区/元数据区存的类对象很少会将其卸载掉 GC 主要分为以下两个阶段 这里涉及到垃圾回收算法基本的思想方法不代表 JVM 真实的实现方式JVM 的真实实现方式是基于这些思想方法但是同时又做出很多细节上的调整和优化~ 3.1 找 —— 谁是垃圾 【如何确认垃圾】 一个对象如果后续不再用了就可以认为是垃圾 在 Java 中使用一个对象只能通过引用如下 如果一个对象没有引用指向它此时这个对象一定是无法被使用的被视为垃圾 如果一个对象已经不想用了但是这个引用可能还指向着这里就不当做垃圾处理 Java 中只是单纯通过引用有没有指向这个操作来判定是否为垃圾Java 中对于垃圾对象的识别是比较保守的最大程度上避免“误杀”释放不及时是小事误杀是大事 【如何找垃圾】 具体来说 Java 如何知道一个对象是否有指向引用呢有两种算法 3.1.1 引用计数法 【引用计数法】给对象安排一个额外空间保存一个整数表示该对象有几个引用指向 Java 实际上没有使用这个方案Python、PHP采取该方案 图解如下 随着引用的增加计数器就增加引用销毁计数器就减少当计数器为0的时候则认为该对象没有引用了就是垃圾 【注意】是每个对象都有一个单独的计数器不是每个类都有一个 但是这会带来一个问题 此时如果 a 和 b 销毁了这个时候两个对象的引用计数各自减1它们的计数器值为 2 - 1为 1这个时候这两个对象引用计数不是 0不能作为垃圾而这两个对象却无法使用了陷入一个逻辑上的循环 【优点】实现简单 【缺点】1. 浪费空间 2.存在循环引用的情况会导致引用计数的判定逻辑出错 3.1.2 可达性分析 【可达性分析】 把对象之间的引用关系理解成了一个树形结构从一些特殊的起点出发进行遍历只要能遍历访问到的对象就是可达的再把不可达的当做垃圾即可 Java没有使用引用计数采用了可达性分析 可达性分析的关键要点就是进行上述遍历需要有起点可以作为起点的 栈上的局部变量每个栈上的局部变量都是起点常量池中引用的对象方法区中静态成员引用的对象 可达性分析简单来说就是从所有的 gcroots 的起点出发通过遍历看看该对象又通过引用能访问哪些对象把所有可以访问的对象都遍历一遍遍历的同时将对象标记成可达剩下的就不可达 【优点】克服了引用计数的两个缺点 【缺点】 1消耗更多的时间因此某个对象成为了垃圾不一定能及时发现因为扫描的过程中需要消耗时间 2在进行可达性分析的时候遍历过程中一旦这个过程中当前代码的对象引用关系发生变化此时就更加麻烦 因此为更准确完成这个过程需要让其它业务线程暂停工作 3.2 释放 —— 把垃圾对象的内存给释放掉 通过上述分析将可回收的对象标记出来了标记出来之后就可以进行垃圾回收操作了如何进行高效的垃圾回收呢以下介绍 4 种算法 3.2.1 标记清除算法 【标记清除算法】直接把垃圾对象内存释放掉 【优点】实现简单 【缺点】这种方式会产生内存碎片申请空间都是申请整块的连续的空间比如总的空闲空间可能超过 1G但是这些空闲的空间都是离散的、独立的可能想申请到 500M 空间都申请不到~ 3.2.2 复制算法 【复制算法】由上述标记清理算法演化而来它将内存容量等大小分为两块每次只使用其中的一块把不是垃圾的对象拷贝到另一边再整个释放这个垃圾区域 【优点】解决内存碎片问题 【缺点】空间利用率低因为复制算法每次只能使用一半的内存如果当前对象大部分都是要保留的垃圾很少则复制成本较高 3.2.3 标记整理算法 【标记整理算法】与标记清除法一样但是不是直接清理可回收对象先有一个移动的的过程将所有存活的对象都向一端移动再清理掉边界以外的内存区域 【优点】解决内存碎片问题比复制算法空间利用率高 【缺点】类似于顺序表有一个搬运的过程因为有局部对象的移动开销比较大效率不是很高 3.2.4 分代算法 实际上JVM 的实现思路结合了上述几种思想方法针对不同的情况使用不同的策略到达取长补短的效果下面具体介绍给算法 —— 分代回收算法 【分代算法】根据对象存活周期不同将内存划分为几块一般将 Java 堆 分为新生代和老年代根据各个年代选择适合的垃圾收集算法 给对象设定了年龄描述这个对象存在的时间如果一个对象刚诞生认为是 0 岁每次经过一轮扫描即可达性分析没有被标记成垃圾这个时候对象就涨一岁通过年龄来区分这个对象的存活时间由经验规律可以得到如果一个对象存活时间很长它将可以继续存在很长时间 由于新生代存放的大部分数据都是朝生夕死的因此新生代使用效率高的复制算法而老生代使用标记清除/标记清理算法哪个好使用哪个 具体过程如下 1新创建的对象放到伊甸区当垃圾回收扫描到伊甸区后绝大部分的对象都会在 GC 中被干掉大部分对象是活不过一岁的由经验规律得知 2如果伊甸区的对象撑过第一轮 GC就会通过复制算法把存活的对象拷贝到生存区 3当这个对象在生存区撑过多轮 GC 后年龄增长到一定程度就会通过复制算法拷贝到老年代 4进入老年代的对象年龄都较大再消亡的概率较低针对老年代的 GC 扫描频次就会降低如果发现老年代中某个对象是垃圾可以使用标记清除/标记清理算法进行清除 垃圾收集器是具体的实现方式具体实现往往是基于上述思想方法做出一些优化和改进包含更多的实现字节Java 版本的变更垃圾回收器也在不断变化~ ✨✨✨本期内容到此结束啦~
http://www.hkea.cn/news/14440207/

相关文章:

  • 怎样做违法网站佛山网站设计哪里好
  • 商城网站包括哪些模块如何同步wordpress
  • 网站建设提供资料表广告设计接单app
  • 彩票网站建设策划书wordpress中文商城模板
  • 注册公司在哪个网站注册百度百度一下首页
  • 清城区做模板网站建设飞鱼网站建设
  • 番号网站怎么做团购网站模块
  • 天天做网站wordpress图片放大滑动
  • 做转运网站女生做ui设计
  • 微信群如何推广网站建设淘宝网站建设图片素材
  • 医院行业的网站是很难做吗怎么建立一个网站网址
  • 做网站工作内容小说网站的内容做
  • 雄县网站制作建设中心客户管理系统crm
  • 网站开发项目经验福州网络推广运营
  • 创意网站布局wordpress 4.8 pdf缩略图
  • 营销型网站设计房地产网站集约化建设工作打算
  • 男女做暖暖的试看网站酥酥影视软件开发培训班价格
  • 网站示例广州微网站建设效果
  • 大连网站建设联合企邦苏州营销型网站建设方案
  • 做相亲网站的安全责任战鼓网h5在线制作
  • 网站右侧浮动广告专业新站整站快速排名公司
  • 网站排版类型个人免费网页
  • 建设网站需要什么知识南京装饰公司网站建设
  • 网站管理与建设总结潍坊专业企业营销策划有哪些
  • 国外的网站用不用备案郑州网站建设培训
  • 宁波网站推广哪家公司好基层人武部正规化建设
  • 免费 个人网站移动端设计规范
  • 做网站设计公司价格网站图片下载 代码
  • 贵阳网站建设电话互联网网络推广
  • 校园门户网站设计论文室内设计平面图讲解