wordpress书籍推荐,优化网站除了百度站长,影视网络推广方案,wordpress wplogin.php目录 1.JVM运行时数据区
2.JVM类加载过程
3.双清委派模型
4.垃圾回收机制#xff08;GC#xff09;
找出谁是垃圾方案一#xff1a;引用计数
找出谁是垃圾#xff1a;方案二#xff0c;可达性分析
释放垃圾的内存空间
判断垃圾#xff1a;jvm依据对象的年龄对 对象…目录 1.JVM运行时数据区
2.JVM类加载过程
3.双清委派模型
4.垃圾回收机制GC
找出谁是垃圾方案一引用计数
找出谁是垃圾方案二可达性分析
释放垃圾的内存空间
判断垃圾jvm依据对象的年龄对 对象进行区域划分。
回收垃圾方式分代回收 1.JVM运行时数据区
JVM运行时数据区域 也叫做JVM内存布局。
JVM内存布局 和 java内存模型完全不同JVM内存布局由5大部分组成。 1.堆区线程共享程序中所有创建的对象都保存在堆中。JVM最大空间。
2.栈线程私有 1.java虚拟机栈作用线程私有Java虚拟机栈的生命周期 和 线程相同Java虚拟机栈描述了java方法执行的内存模型每个方法在执行时 都会创建一个栈帧用来储存局部变量方法之间的调用关系动态链接方法出口等等。 2.本地方法栈与虚拟机栈类似只不过是给本地方法使用的本地方法由C代码编写。
3.程序计数器线程私有保存下一条要执行的指令的地址。这里不是CPU寄存器储存的而是内存空间指令是java的字节码。不是二进制机器语言。
4.元数据区以前叫方法区保存java代码中涉及类的相关信息。类的static属性。 在一个java进程中元数据区 和 堆 是只有一份的。即同一个进程中的所有线程共用一份数据。
一个java进程中有多个线程多个线程都有自己的 程序计数器 和 栈。所以每个线程都需要保存自己的“程序计数器” 每个线程都需要记录自己的 调用关系。 检测一下是掌握的怎么样下面代码中的变量都储存在哪些区域
public class test4 {static class Test{private int a;private Test b new Test();private static int c;private static Test d new Test();}public static void main(String[] args) {int e 10;Test f new Test();}
} 一般地
局部变量栈
成员变量堆
静态成员变量元数据区方法区 2.JVM类加载过程
一个类的生命周期大致为下几个过程。 编写一个java程序 会得到一个 .java文件在经过javac 编译 就会得到一个 .class文件。
想要运行java 进程jvm就需要 读取 .class 文件并执行里面的指令。
jvm读取到 .class里面的内容 这个就是类加载。把类 涉及的字节码从硬盘读取到 内存里。 加载一个 .claas文件就会对应创建一个类对象。类对象包含了.class
文件里的各种信息。
类名字类的属性类有哪些方法继承的父类有哪些实现的接口有哪些.... 具体步骤
1.加载把 .class 文件找到然后打开并读取文件的内容。
代码中先见到 类的名字然后进一步找到对应的 .class 文件涉及一系列的目录查找过程
2.验证验证读到的 .class 文件的数据是否正确是否合法。
java标准文档中明确规定 .class 文件的格式是怎么样的。
3.准备分配内存空间。
根据读取到的内容大小确定出类对象需要的内存空间申请这样大小的空间并把这个空间全部初始化为0.
4.解析主要针对类中的字符串常量进行处理
java虚拟机 将字符串常量池中的 符号引用 替换为直接引用的过程也就是初始化常量。
符号引用 其实就是指字符串常量已经在 .class文件中文件中 符号的位置就是偏移量。
直接引用 就是直接保存变量的地址。 5.初始化针对 类对象 做最终的初始化操作执行静态成员赋值语句。 3.双清委派模型
操作 输入一个 类的全限定名类似于java.lang.String),的到对应的 .class 文件。
属于 jvm加载类中的第一个机制加载 Bootstrap ClassLoader(加载 标准库中的类
ExtensionClassLoader(加载 扩展库的类
ApplicationClassLoader(负责加载第三方库的类 为什么会是这个流程
核心目的是 方式用户自己写的类把 标准库 或者 扩展库给覆盖掉。
保证 标准库的类是第一位扩展库的类的是第二位。最后是第三方库的类。
防止程序员 不小心创建一个 和 系统中已有的类重名的类。导致加载的时候覆盖掉了系统的类。 4.垃圾回收机制GC
GC 主要存在哪里呢
栈 和 程序计数器 主要都是跟随线程的结束而结束。
元数据区类对象涉及到的类加载一个程序里面吗要加载得类都是有上限的不会出现无限增长的情况。
所以 堆是GC得主要战区。
垃圾回收回收内存 都是一对象为维度进行回收的。 GC回收的流程1.找出谁是垃圾 2.释放垃圾的内存空间
找出谁是垃圾方案一引用计数
给每个对象分配一个计数器衡量有多少个引用指向。
每增加一个引用计数器1
每减少一个引用计数器-1如果计数器为0此对象就垃圾了需要回收。 此时 对象中的计数器为0就视为垃圾需要回收。
上述方案存在两个问题
1.消耗额外空间去 储存计数器
假设Tets类只有一个int4字节成员那么就要花2个字节储存计数器内存多用了 50%
2.引用计数可能会导致“循环引用”使得上述判定出错。 这种情况就是最后 这俩对象计数器都不是0都不能被释放。 找出谁是垃圾方案二可达性分析
用时间换取空间。
JVM中专门搞了一波周期性的线程扫面代码中的所有对象判定某个对象是否“可达”。
对应的不可达的就是垃圾。
JVM中有所有对象的总名单按照名单点名如果没有到的 就是垃圾。
JVM中有很多的root根从这个root开始可以把所有的对象都遍历到。遍历不到但是名单上存在就是垃圾。 释放垃圾的内存空间
1.标记-清除法
如果直接对内存空间进行标记清楚就有可能导致碎片化的空间无法充分利用。 这样剩下的三个空间就不容易利用了碎片化的空间不能进行申请连续的空间。
2.复制算法
将被回收后的空间的一分为二把不是垃圾的对象拷贝到另一侧。确保回收后得到连续的空间 这个算法缺点很明显
1.内存空间利用率低
2.如果存活下来的对象比较多复制成本也很大。
3.标记-整理
与标记-清楚类似但是不一样的是后续并不是直接回收对象而是让所有的存活对象都向前移动最后直接清理掉边界标记的就可以了。 4.jvm中真正的解决方案。
判断垃圾jvm依据对象的年龄对 对象进行区域划分。
如果获得年龄使用可达性分析 对对象进行扫描每次描扫后对象的年龄就1 1.伊甸区比较大让新创建的对象存放大多数新创建的对象都活不过第一轮GC留下来的对象拷贝到幸存区。
2.幸存区是两个相按照复制算法将存活久对象复制到幸存区反复多次。幸存区里也会为了保留完整空间进行左右多次复制。
3.一个对象在幸存区多次被拷贝年龄不断增长就要拷贝到老年代了。
4.根据经验规律老年代的对象生命周期都比较长即便如此也是要进行可达性分析的。
但是老年代的GC频率较低。老年代也需要通过标记整理。 回收垃圾方式分代回收
分代回收时JVM的GC基本思想方法。
jvm还提供许多“垃圾回收器”对上述的分代回收 作进一步的扩充和具体实现。 CMS涉及理念把整个GC过程拆分成多个阶段能和业务线程并发运行的。就尽量并发减少STW时间。 G1把整个内存分成很多快不同的颜色表示这个一块区域是哪一块新生代老年代幸存区...)
进行GC时不要求一周期就把多个内存都回收只要回收一部分就好。限制一轮GC的工作量目的是使STW控制在一定范围降低STW的影响。