网站开发上海,东莞住建局网,常宁市城市建设规划管理局网站,精准网络推广1. JVM 内存区域划分 一个运行起来的 Java 进程#xff0c;就是一个 JVM 虚拟机#xff0c;需要从操作系统申请一大块内存#xff0c;就会把这个内存#xff0c;划分成不同的区域#xff0c;每个区域都有不同的作用. JVM 申请了一大块内存之后,也会划分成不同的内…1. JVM 内存区域划分 一个运行起来的 Java 进程就是一个 JVM 虚拟机需要从操作系统申请一大块内存就会把这个内存划分成不同的区域每个区域都有不同的作用. JVM 申请了一大块内存之后,也会划分成不同的内存区域下面来详细讲解一下各个区域 1、方法区 (jdk1.7 及其之前)/ 元数据区 (jdk1.8 开始) 这里存储的内容,就是类对象。.class 文件加载到内存之后就成了类对象。 2、堆 这里存储的内容,就是代码中 new 的对象(该区域是占据空间最大的区域) 3、栈 这里存储的内容,就是代码执行过程中,方法之间的调用关系如下图所示 4. 程序计数器 是一个比较小的空间主要就是存放一个地址,表示下一条要执行的指令在内存中的哪个地方方法区里每个方法里面的指令, 都是以二进制的形式保存到对应的类对象中的刚开始调用方法程序计数器记录的就是方法的入口的地址随着一条一条的执行指令,每执行一条,程序计数器的值都会自动更新即去指向下一条指令 如果是一个顺序执行的代码下一条指令就是把指令地址进行递增 如果是条件/循环代码下一条指令就可能会跳转到一个比较远的地址 下面进行举例 主要知识点如下图所示 本地方法指的是使用 native 关键字修饰的方法.这个方法不是使用 java 实现,而是在jvm 内部通过 C 代码实现的JVM 内部的 C 代码调用关系 虚拟机栈,以及程序计数器都是每个线程都有一份JVM 进程中有 10 个线程就会有 10 个虚拟机栈,也会有 10 个程序计数器(每个线程各自有一个 堆区和元数据区这俩东西在 JvM 进程中是只有一份的 下面给你一个代码,问你某个变量是处于内存中的哪个区域中 一个变量处于哪个区域,和变量的形态密切相关局部变量处于栈上。成员变量在堆上静态变量在与数据区内同时我们要知道变量处于哪个空间上,和变量是不是引用类型,是不是基本类型是没有关系的 new 出来的对象在堆上于此同时又创建了一个局部变量 Test t引用类型的变量,就把对象地址存储到t里面了t里面存储的不是对象本身 一个 JvM 进程里,可能有多个线程.每个线程,有自己的程序计数器和栈空间这些线程共用同一份堆和方法区 2. jvm中类加载的过程 java 代码会被编译成.class 文件(包含了一些字节码)java 程序要想运行起来,就需要让 jvm读取到这些.class 文件,并且把里面的内容,构造成类对象并保存到内存的方法区中.所谓的执行代码”就是调用方法.就需要先知道每个方法编译后生成的指令都是啥 一般来说将整个类加载的过程分为5个部分
2.1 加载 找到 .class 文件,打开文件,读取文件内容 往往代码中会给定某个类的,全限定类名“例如java.lang.Stringjava.util.ArrayListjvm 就会根据这个类名,在一些指定的目录范围内查找.
2.2 .验证 .class 文件是一个二进制的格式,(每一个字节,都是有某些特定含义的)就需要验证你当前读到的这个格式是否符合要求. 下图就是.class文件需要遵循的格式 2.3 准备 给类对象分配内存空间 (最终的目标就是要构造出 类对象) 我们这一步只是分配内存空间,还没有初始化呢.此时这个空间上的内存的数值,就是全0 ,(此时如果尝试打印类的 static 成员,结果就是全0的)
2.4 解析 针对类对象中包含的字符串常量进行处理, 进行一些初始化操作java 代码中用到的字符串常量在编译之后,也会进入到 .class 文件中下面通过对字符串s的解析进行进一步说明 于此同时,.class 文件的二进制指令中,也会有一个s这样的引用被创建出来由于引用里面本质上保存的是一个变量的地址,在 .class 文件中,这是文件不涉及到内存地址因此住 .class 文件中,s 的初始化语句即先会被设置成一个“文件偏移量”通过偏移量就能找到test这个字符串所在的位置 下面来简单说明一下文件偏移量 接下来 这个过程,也叫做: 把符号引用(文件偏移量)替换成“直接引用)(内存地址) 2.5 初始化 针对类对象进行初始化 把类对象中需要的各个属性都设置好同时还需要初始化好 static 成员变量还需要执行静态代码块以及还可能需要加载一下父类.
2.6 双亲委派模型 双亲委派模型属于类加载中第一个步骤-加载过程中的一个环节主要是根据负责根据全限定类名来找到 .class 文件. 类加载器是 JVM 中的一个模块JM 中中内置了下面如图所示的三个类加载器 如上图所示这个父子关系并不是“继承构成的而是这几个 ClassLoader 里有一个 parent 这样的属性指向了一个 父类加载器 下面来详细描述一下类加载的过程(即找 .class 文件的过程) 1、给定一个类的全限定类名,形如 java.lang.String 2、从 Application ClassLoader 作为入口,开始执行査找的逻辑 3、Application ClassLoader不会立即去扫描自己负责的目录(负责的是搜索项目当前目录和第三方库对应目录而是把查找的任务交给它的父亲,Extension ClassLoade 4、 Extension ClassLoader,也不会立即扫描自己负责的目录(负责的是 JDK 中一些扩展的库所对应的目录)而是把查找的任务交给它的父亲BootStrap ClassLoade 5、Bootstrap ClassLoader,也不想立即扫描自己负责的目录(负责的是 标准库 的目录)也想把任务交给它的父亲,结果发现,自己没有父亲因此 BootStrap ClassLoader 只能亲自负责扫描标准库的目录如下所示 像java.lang.String.这种类,就能够在标准库中,找到对应的 .class 文件,就可以进行打开文件,读取文件......此时,查找 .class 文件的过程就结束了但是,如果给定的类不是标准库的类,任务仍然会被交给孩子来执行 6、没有扫描到就会回到 Extension ClassLoader.Extension ClassLoader 就会扫描负责的扩展库的目录.如果找到,就执行后续的类加载操作,此时查找过程结束还没有没找到,就会把任务交给他的孩子来执行. 7、没有扫描到, 就会回到 Application ClassLoade)Application ClassLoader 就会负责扫描当前项目和第三方库的目录.如果找到,就执行后续的类加载操作.如果没找到,就会抛出一个 ClassNotFoundException 综上所述所谓的“双亲委派模型“其实就是一个查找优先级的问题简单的查找流程如下图所示 之所以搞这一套流程主要的目的是为了确保标准库的类被加载的优先级最高其次是扩展库,其次是自己写的类和第三方库 3. GC 垃圾回收 C 语言中像 malloc 这种, 就属于是动态申请内存”运行时其实很多时候, 需要程序真正跑起来,才能确定内存的大小 在C 语言中, 使用 malloc 申请的内存需要在用完之后, 通过 free 来释放。此处如果不释放,就会产生内存泄露”这样的问题 C里,动态申请内存,变成 newmalloc 只是申请内存.new,能够申请内存,也能初始化(调用构造函数)在C 中,使用 new 申请的内存用完之后, 通过 delete 来释放 在 Java 中, new 一个对象也就是动态内存申请” 综上所述相比之下, java 给出了一个方案垃圾回收机制 (GC)让 JVM 自行判定,某个内存是否就不再使用了如果这个内存后面确实不用了,JVM 就自动的把这个内存给回收掉此时就不必让程序猿自己手动写代码回收 下面首先来了解一下GC机制的缺陷 1.系统开销需要有一个或一些特定的线程,不停的扫描内存中的所有的对象, 看是否能够回收此时是需要额外的内存和CPU 资源的. 2.效率问题这样的扫描线程,不一定能够及时的释放内存(扫描总是有一定周期的)一旦同一时刻,出现大量的对象都需要被回收,GC 产生的负担就会很大.甚至引起整个程序都卡顿.(STW 问题即stop the world) GC 是垃圾回收GC 回收的目标其实是内存中的对象对于 Java 来说, 就是 new 出来的这些对象栈里的局部变量是跟随着栈帧的生命周期走的,(方法执行结束,栈帧销毁该部分的内存自然释放)静态变量的生命周期就是整个程序这个始终存在就意味着静态变量是无需释放的因此真正需要 gc 释放的, 就是堆上的对象了. gc 可以理解成两个大的步骤: 1. 找到垃圾 2. 释放垃圾 3.1 找到垃圾 在 GC 的领域中, 有两种主流的方案: 1)、引用计数 [Python, PHP] new 出来的对象,单独安排一块空间,来保存一个计数器如下图所示 在Java 中,使用对象,必须要依靠引用如果一个对象,没有引用指向了,就可以视为是垃圾了(引用计数就是0 ) 对于上述代码出了 { }之后t 和 t2 就都销毁了即引用计数就要归0了当对象的引用计数为 0,此时代码中就不可能访问到这个对象了此时这个对象就可以视为是垃圾了 关于 java 不使用引用计数的分析引用计数存在两个重要的问题: 1、比较浪费内存. 计数器最少需要2个字节如果对象本身就很小,这个计数器占据的空间比例就很大 比如对象本身就 2 个字节,计数器占据的空间就是 50%如果对象本身 4个字节?计数器占据的空间就是 33% 如果对象很少, 或者对象比较大, 都影响不大。但是如果对象小并且很多,计数器所占据的空间就十分巨大 2、引用计数机制,存在循环引用”问题如下面的一段代码所示 ab及其引用的内存分布如下所示 此时,当前a和 b 两个引用已经销毁了new 出来的这俩对象,已经无法被其他代码访问到了但是他们的引用计数却是不为0的所以这俩对象是不能被回收的此时,第一个对象引用了第二个对象,第二个对象引用了第一个对象. 2)、可达性分析 【java】 可达性分析本质上是时间换空间的手段 有一个/一组线程周期性的扫描我们代码中所有的对象从一些特定的对象出发,尽可能的进行访问的遍历把所有能够访问到的对象,都标记成“可达”反之,经过扫描之后, 未被标记的对象,就是垃圾 不仅仅是所有的局部变量还有常量池中引用的对象还有方法区中的静态引用类型引用的变量都统称为 GCRoots当然,这里的遍历大概率是 N 叉树.主要就是看所访问的某个对象里面有多少个引用类型的成员并针对每个引用类型的成员都需要进一步的进行遍历 可达性分析都是周期性进行的当前某个对象是否是垃圾是随着代码的执行而发生改变总之就是可达性分析比较消耗系统资源,开销比较大 3.2 回收垃圾
3.2.1 标记清除 该方式是比较简单粗暴的释放方式下面黑色区域是被标记的要被清除的 把对应的对象,直接释放掉,就是标记清除的方案但是这个方案其实非常不好因为会产生很多的内存碎片释放内存的主要目的是为了让别的代码能够申请到连续”的内存空间但是这样会导致我们能用的内存是断断续续的随着时间的推移,内存碎片的情况就会越演越烈如此就会导致后续内存申请举步维艰.
3.2.2 复制算法 通过复制的方式,把有效的对象归类到一起.再统一释放剩下的空间 把内存分成两份,一次只用其中的一半这个方案可以有效解决内存碎片的问题.但是缺点也很明显 1、内存要浪费一半,利用率不高 2、如果有效的对象非常多,拷贝开销就很大
3.2.3 标记整理 既能够解决内存碎片的问题,又能处理复制算法中利用率 类似于顺序表删除元素的搬运操作 3.2.4 分代回收 实际上,JVM 采取的释放思路是上述基础思路结合体分代回收对象能活过的 GC 扫描轮次越多, 就是越老 伊甸区 刚 new 的新的对象放到伊甸区从对象诞生,到第一轮可达性分析扫描,这个过程中 虽然时间不长(往往就是毫秒或秒)但是,在这个时间里大部分的对象都会成为垃圾 释放过程如下所示 1)、伊甸区 幸存区 使用复制算法每一轮 GC 扫描之后, 都把有效对象复制到幸存区中,伊甸区就可以整个释放了由于经验规律,真正需要复制的对象不多所以非常适合复制算法 2)、GC 扫描线程也会扫描幸存区. 就会把活过GC 扫描的对象(扫描过程中可达)拷贝到幸存区的另一个部分幸存区之间的拷贝,每一轮会拷贝多个对象每一轮也会淘汰掉一批对象(有些对象随着时间的推移,就成了垃圾) 3)、当这个对象已经在幸存区存活过很多轮 GC 扫描之后JVM 就认为这个对象,短时间内应该是释放不掉了就会把这个对象拷贝到老年代 4)、进入老年代的对象, 虽然也会被 GC 扫描但是老年代 GC 扫描的频率就会比新生代 分代回收,是 JVM 中主要的回收的思想方法.但是在垃圾回收器具体实现的时候,可能还会有一些调整和优化. ps到这里java ee初阶的内容就结束了感谢陪伴了很久的自己尤其是在上完班后晚上敲写博客的自己还是那句话虽然多阻滞花发再重荣 文章转载自: http://www.morning.hxcrd.cn.gov.cn.hxcrd.cn http://www.morning.yrskc.cn.gov.cn.yrskc.cn http://www.morning.fksrg.cn.gov.cn.fksrg.cn http://www.morning.kgtyj.cn.gov.cn.kgtyj.cn http://www.morning.wkmpx.cn.gov.cn.wkmpx.cn http://www.morning.mlpch.cn.gov.cn.mlpch.cn http://www.morning.lhxrn.cn.gov.cn.lhxrn.cn http://www.morning.bncrx.cn.gov.cn.bncrx.cn http://www.morning.hbdqf.cn.gov.cn.hbdqf.cn http://www.morning.chbcj.cn.gov.cn.chbcj.cn http://www.morning.yzygj.cn.gov.cn.yzygj.cn http://www.morning.mqnbm.cn.gov.cn.mqnbm.cn http://www.morning.wqrk.cn.gov.cn.wqrk.cn http://www.morning.rcmwl.cn.gov.cn.rcmwl.cn http://www.morning.pynzj.cn.gov.cn.pynzj.cn http://www.morning.thbnt.cn.gov.cn.thbnt.cn http://www.morning.qdrhf.cn.gov.cn.qdrhf.cn http://www.morning.fwwkr.cn.gov.cn.fwwkr.cn http://www.morning.jxhlx.cn.gov.cn.jxhlx.cn http://www.morning.ssrjt.cn.gov.cn.ssrjt.cn http://www.morning.tnktt.cn.gov.cn.tnktt.cn http://www.morning.gxcit.com.gov.cn.gxcit.com http://www.morning.xhsxj.cn.gov.cn.xhsxj.cn http://www.morning.lsnnq.cn.gov.cn.lsnnq.cn http://www.morning.lsfbb.cn.gov.cn.lsfbb.cn http://www.morning.lgwpm.cn.gov.cn.lgwpm.cn http://www.morning.gwqq.cn.gov.cn.gwqq.cn http://www.morning.dgng.cn.gov.cn.dgng.cn http://www.morning.syglx.cn.gov.cn.syglx.cn http://www.morning.qttg.cn.gov.cn.qttg.cn http://www.morning.ncfky.cn.gov.cn.ncfky.cn http://www.morning.sqgsx.cn.gov.cn.sqgsx.cn http://www.morning.nnqrb.cn.gov.cn.nnqrb.cn http://www.morning.rnqrl.cn.gov.cn.rnqrl.cn http://www.morning.zpxwg.cn.gov.cn.zpxwg.cn http://www.morning.qrmry.cn.gov.cn.qrmry.cn http://www.morning.nkcfh.cn.gov.cn.nkcfh.cn http://www.morning.nfpkx.cn.gov.cn.nfpkx.cn http://www.morning.ynryz.cn.gov.cn.ynryz.cn http://www.morning.dmtld.cn.gov.cn.dmtld.cn http://www.morning.dqwkm.cn.gov.cn.dqwkm.cn http://www.morning.jbblf.cn.gov.cn.jbblf.cn http://www.morning.xfxnq.cn.gov.cn.xfxnq.cn http://www.morning.ylkkh.cn.gov.cn.ylkkh.cn http://www.morning.xknmn.cn.gov.cn.xknmn.cn http://www.morning.yrjxr.cn.gov.cn.yrjxr.cn http://www.morning.xq3nk42mvv.cn.gov.cn.xq3nk42mvv.cn http://www.morning.mqtzd.cn.gov.cn.mqtzd.cn http://www.morning.gkmwk.cn.gov.cn.gkmwk.cn http://www.morning.ynryz.cn.gov.cn.ynryz.cn http://www.morning.flxqm.cn.gov.cn.flxqm.cn http://www.morning.sjwiki.com.gov.cn.sjwiki.com http://www.morning.zzfqn.cn.gov.cn.zzfqn.cn http://www.morning.fesiy.com.gov.cn.fesiy.com http://www.morning.ghzfx.cn.gov.cn.ghzfx.cn http://www.morning.rmyt.cn.gov.cn.rmyt.cn http://www.morning.pfnrj.cn.gov.cn.pfnrj.cn http://www.morning.hwcgg.cn.gov.cn.hwcgg.cn http://www.morning.ppwdh.cn.gov.cn.ppwdh.cn http://www.morning.mm27.cn.gov.cn.mm27.cn http://www.morning.qxwwg.cn.gov.cn.qxwwg.cn http://www.morning.lqjlg.cn.gov.cn.lqjlg.cn http://www.morning.gnkdp.cn.gov.cn.gnkdp.cn http://www.morning.okiner.com.gov.cn.okiner.com http://www.morning.pltbd.cn.gov.cn.pltbd.cn http://www.morning.iiunion.com.gov.cn.iiunion.com http://www.morning.c7617.cn.gov.cn.c7617.cn http://www.morning.rqpgk.cn.gov.cn.rqpgk.cn http://www.morning.yrdn.cn.gov.cn.yrdn.cn http://www.morning.jmwrj.cn.gov.cn.jmwrj.cn http://www.morning.znpyw.cn.gov.cn.znpyw.cn http://www.morning.pqktp.cn.gov.cn.pqktp.cn http://www.morning.fcqlt.cn.gov.cn.fcqlt.cn http://www.morning.yszrk.cn.gov.cn.yszrk.cn http://www.morning.wjrtg.cn.gov.cn.wjrtg.cn http://www.morning.qcygd.cn.gov.cn.qcygd.cn http://www.morning.ybgpk.cn.gov.cn.ybgpk.cn http://www.morning.lsjtq.cn.gov.cn.lsjtq.cn http://www.morning.fqmbt.cn.gov.cn.fqmbt.cn http://www.morning.clhyj.cn.gov.cn.clhyj.cn