java的跨平台原理:.java源文件通过编译生成.class文件字节码文件,然后由java虚拟机加载并运行。
什么是类加载器:用来加载class字节码文件到内存中 类加载机制分为两种:隐式加载,显示加载 隐式加载:通过new关键字 显示加载:通过反射的Class.forname() 类加载机制:类加载机制分为五个阶段,加载,连接,初始化,使用,卸载。
注意一个类,只能被加载一次。
加载:根据类的全限定名将类的字节码文件加载到内存中,并将类的所有信息封装到Class对象里面,将Class对象放入方法区中,然后在堆中创建java.lang.Class对象来进行关联这个类(反射就是直接操作这个对象),这个过程由类加载器完成。 连接:分为三个阶段 1.验证:此阶段验证当前字节码文件是否符合java的规范,没有存在安全隐患。 2.准备:正式为类变量分配内存空间(仅仅是分配内存空间,没有赋值此时还是默认值)。 3.解析:将变量的符号引用替换成直接引用 初始化:正式为类进行初始化,初始化静态变量并赋值,执行静态代码块,为普通属性开辟空间进行设置默认值。 当加载一个类时如果这个类有其父类会优先加载其父类。Object类除外因为它没有父类。 当将类加载到内存后,我们就可以使用new关键字操作对象了。 当使用new关键字的时候会在内存中复制出一个对象出来,JVM会为对象分配内存空间。
JVM分配内存空间分为两种:指针碰撞,空闲列表。
指针碰撞:当java的内存空间是规整的,将使用指针碰撞的分配方式。 当使用new关键字创建对象的时候,首先在堆中存在一个指针,他将移动一块和当前的创建对象相等的空间(这也是为什么对象默认值是null的原因),然后将对象存入到这个空的内存空间中。
空闲列表:当java的内存空间不是规整的,也就是说有很多琐碎的空白的内存,将使用空闲列表的分配方式。 在JVM中维护了一张保存空闲内存空间的列表,当创建出来一个新的对象会在这张列表里面找是否有空着的符合当前新对象的内存大小,然后将对象保存在符合的空间中。
内存地址是否规整取决于gc是否使用了压缩算法。