JVM的基础知识,温故知新

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

1.JVM内存图

image-20191123193343212

橙色为线程共享,灰色为线程独有

2.ClassLoader有几种

虚拟机自带的加载器

  1. 启动类加载器 Bootstrap Class Loader
  2. 扩展类加载器 Extension Class Loader
  3. 应用程序类加载器 App Class Loader

用户自定义加载器

java.lang.ClassLoader的子类

问 :Object.getParent()和自定义MyObject.getParent()值?

      Object object = new Object();
System.out.println(object.getClass().getClassLoader());//null

MyObject myObject = new MyObject();
//sun.misc.Launcher$AppClassLoader@
System.out.println(myObject.getClass().getClassLoader());

//sun.misc.Launcher$ExtClassLoader@
System.out.println(myObject.getClass().getClassLoader().getParent());

//null
System.out.println(myObject.getClass().getClassLoader().getParent().getParent());

3.双亲委派机制

(我爸是李刚,有事找我爹)类加载

使用一个类先到顶部的类加载器去找看是否有实现,再向下寻找

如果我手动创建一个java.lang包,创建String类 运行发生什么?


public class String {
public static void main(String[] args) {
System.out.println("--------");
}
}
错误: 在类 java.lang.String 中找不到 main 方法, 请将 main 方法定义为:
public static void main(String[] args)
否则 JavaFX 应用程序类必须扩展javafx.application.Application

4.pc寄存器

指针,指着方法运行完下一个要执行的方法。每个线程都有一个pc寄存器,线程私有。

5.方法区

各线程共享的运行时内存区域。储存每一个类的结构信息,例如运行时常量池,字段和方法数据,构造函数和普通方法的字节码内容

典型实现是为 永久代和元空间。

6.栈管运行,堆管存储

栈不存在垃圾回收问题,线程私有

栈内存储存:8种基本类型变量+对象引用实例+实例方法

栈帧(java方法)中主要保存本地变量,栈操作栈帧数据。

StackOverflow 是 error,不是异常。

栈,堆,方法区的交互

image-20191124142323090

7.堆

新生区 养老区 永久区(元空间)

image-20191124142937705

新生区 1/3堆空间

eden 8/10 from(s0) 1/10 to(s1) 1/10

养老区 2/3 堆空间

gc过后有复制,谁空谁是to,15次(默认)进养老区

堆参数调优

-Xms 初始化大小 默认为物理内存的1/64

-Xmx 最大化 默认为物理内存的1/4

-Xmn new区大小(新生区)

8.GC(分代回收算法)

新生区

引用计数法(基本不用)

复制算法

养老区

标记清除

标记压缩

[GC算法 垃圾回收器](https://www.cnblogs.com/ityouknow/p/5614961.html"With a Title”)

9.JMM(java内存模型)

抽象,不真实存在,定义程序中变量的访问方式。

volatile 轻量级同步机制(保证可见性,不保证原子性,禁止指令重排)

可见性(多线程通知机制) 原子性 有序性

线程对变量的操作必须在工作内存中进行,先从主物理内存拷贝到线程的工作内存,然后再对变量进行操作,操作完成后再将变量写回主内存。

image-20191112171612473