先简单说下java虚拟机内存模型和存放内容的区别,两部分:
栈内存 存放基本类型数据和对象的引用变量,数据可以直接拿来访问,速度比堆快
堆内存 存放创建的对象和数组,会由java虚拟机的自动垃圾回收来管理(GC),创建一个对象放入堆内的同时也会在栈中创建一个指向该对象堆内存中的地址引用变量,下面说的对象就是存在该内存中
一个java文件会在编译期间被初始化生成.class字节码文件,字节码文件是专门给JVM阅读的,我们平时吭哧吭哧写的一行行代码最终都会被编译成机器能看懂的语句,这个文件后面会被类加载器加载到内存。
《深入理解Java的虚拟机》中大概有这么一句话:在虚拟机遇到一条new的指令时,会去检查一遍在静态常量池中能否定位到一个类的符号引用 (就这个类的路径+名字),并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果不是第一次使用,那必须先执行相应的类加载过程,这个过程由类加载器来完成。
类加载字面意思就可以理解成加载class文件,更准确点的说法就是会把class文件变成一个二进制流加载到内存中,即把类的描述信息加载到Metaspace,至于类加载器如何找到并把一个class文件转成IO流加载到内存中
在加载类完毕后,对象的所需大小根据类信息就可以确认了,具体创建的步骤如下:
先给对象分配内存(包括本类和父类的所有实例变量,不包括上面的静态变量),并设置默认值,如果有引用对象那么会在栈内存中申请一个空间用来指向的实际对象。
执行初始化代码实例化,先初始化父类再初始化子类,赋予给定值(尊重长辈是java的传统美德)
对象实例化完毕后如果存在引用对象的话还需要把第一步的栈对象指向到堆内存中的实际对象,这样一个真正可用的对象才被创建出来。
可以简单理解②③④为初始化⑤实例化:
几个重要概念:
类加载器,可以找找网上的资料,蛮多的,这块内容做个了解就行
Class类和Class对象的概念,请重点掌握,不然理解反射和动态代理很费劲,spring的源码也会难以理解
栈内存和堆内存以及对应的基本类型和引用类型,也很重要,争取能基本理解