写点什么

【架构师训练营 1 期】第九周学习总结

用户头像
诺乐
关注
发布于: 2020 年 11 月 23 日

(学习笔记与总结整理)


一、JVM

1.Java 虚拟机

Java 是一种跨平台的语言,JVM 屏蔽了底层系统的不同,为 Java 字节码文件构造了一个统一的运行环境。

通过 tomcat 容器会执行 main 方法,类加载器会把 main 下相关的方法和类都加载到方法区中,然后开始执行 main 里面的方法,如果 new 一个对象当前线程的栈帧会将对象放入到堆中并指向堆中的地址,Java 栈和程序计数器都是线程私有的。


2.Java 字节码文件

java 所有的指令 200 多个,一个字节(8 位)就可以表示 256 个指令。在代码执行过程中,JVM 将字节码解释执行,摒弃对操作系统的依赖,也可以将字节码编译执行,如果是热点代码会通过 JIT 动态编译为机器码,来提升效率。


3.类加载器的双亲委托模型

低层次的当前类加载器,不能覆盖更高层次类加载器已经加载的类。如果低层次的类加载器想加载一个未知类,需要上级类加载器确认,只有当上级类加载器没有加载过这个类,也允许加载的时候,才让当前类加载器加载这个未知类。


4.自定义类加载器

隔离加载类:同一个 JVM 中不同组件加载同一个类的不同版本。

扩展加载源:从网络、数据库等处加载字节码。

字节码加密:加载自定义的加密字节码,在 ClassLoader 中解密。


5.栈、堆、方法区之间的关系

Java 程序运行时(简要将内存划分成三种:一种是栈内存,一种是堆内存,一种是方法区)

函数运行时,先从 main 函数进入程序,从上往下运行,获取基本类型的变量,存于栈中。

创建一个新对象,在堆中存放新建的对象,并初始化对象属性,并将对象的地址放在栈中,以便于对应查找对象的数据。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java 会自动释放掉为该变量分配的内存空间,该内存空间可以立即被另作它用。当方法被使用时从方法区进入栈中进行运算的过程被称为进栈或压栈,将方法的运行结果存到相应位置后,此方法作用结束,从栈中被释放的过程被称为出栈或弹栈。


6.线程工作内存 & volatile

Java 内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行。

一个共享变量 (类的成员变量、类的静态成员变量)被 volatile 修饰之后,那么就具备了两层语义:

①保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

②是禁止进行指令重排序。


正常来说每个线程都有一个工作内存,当访问堆中的元素的时候 都会先更改工作内存中的,然后才会刷到主存中,但使用了 volatile 的时候就会直接刷到主存,然后各个线程的工作内存都会去主存中读取。


二、垃圾回收

1.JVM 的垃圾回收

JVM 垃圾回收就是将 JVM 堆中的已经不再被使用的对象清理掉,释放宝贵的内存资源。

JVM 通过一种可达性分析算法进行垃圾对象的识别,具体过程是:从线程栈帧中的局部变量,或者是方法区的静态变量出发,将这些变量引用的对象进行标记,然后看这些

被标记的对象是否引用了其他对象,继续进行标记,所有被标记过的对象都是被使用的对象,而那些没有被标记的对象就是可回收的垃圾对象了。


2.进行完标记以后, JVM 就会对垃圾对象占用的内存进行回收,回收主要有三种方法

①清理:将垃圾对象占据的内存清理掉,其实 JVM 并不会真的将这些垃圾内存进行清理,而是将这些垃圾对象占用的内存空间标记为空闲,记录在一个空闲列表里,当应用程序需要创建新对象的时候,就从空闲列表中找一-段空闲内存分配给这个新对象。

②压缩:从堆空间的头部开始,将存活的对象拷贝放在一-段连续的内存空间中,那么其余的空间就是连续的空闲空间。

③复制:将堆空间分成两部分,只在其中一部分创建对象,当这个部分空间用完的时候,将标记过的可用对象复制到另一个空间中。


3.Jvm 分代垃圾回收:java 不断创建的对象大部分都是很快回收的(一个请求几百 ms 会创建很多对象),对象已创建出来就放到新生代。在 Eden 创先对象当 Eden 满了之后会执行 yung gc 然后把活的对象放到 from 区,然后下次当 Eden 满了之后,进行 gc 然后 Eden 跟 from 会再次进行标记,放入到 to 区域,然后下次会将 Eden 和 to 放到 from,一直重复过程,多次之后就会拷贝到老年代,当 Eden+from 都拷贝不到老年代就会进行一次 Full gc。


4.JVM 垃圾收集器

串行收集器中间 stop the world 的时间会很长

并行收集器,采用多线程的方式来缩短 stop the world 的时间 但还是会有停顿

CMS 并发回收器,会进行初始化标记(停顿标记 root 节点),并发标记和重标记的过程,大幅度缩小停顿时间,在并发的时候进行清理。

用户头像

诺乐

关注

还未添加个人签名 2018.12.01 加入

还未添加个人简介

评论

发布
暂无评论
【架构师训练营 1 期】第九周学习总结