1.jvm内存区域。
jvm内存区域主要分为共享区和线程私有区。共享区分为堆和方法区。堆内存主要存放实例对象、此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。
方法区主要是方法区属于是 JVM 运行时数据区域的一块逻辑区域,是各个线程共享的内存区域。当虚拟机要使用一个类时,它需要读取并解析 Class 文件获取相关信息,再将信息存入到方法区。方法区会存储已被虚拟机加载的 类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。在jdk1.7之后被放入了堆中。还有一个字符串常量池,避免字符串被重复创建。
线程私有区域分为程序计数器、虚拟机栈、本地方法栈、程序计数器主要记录程序字节码的命令,当字节码解释器通过改变程序计数器来依次读取代码,进而实现代码的流程控制。
虚拟机栈会为每一个方法创建一个栈帧,栈帧主要包含局部变量表、操作数栈、动态链接、方法返回地址。
本地方法栈调用被native标识的本地方法。
2.垃圾回收机制
垃圾收收机制主要是在堆内存中,堆内存一般分为年轻代、老年代、持久代。其中年轻代又可分为三个区域eden区,so,s1区。当eden区占满之后,执行一次minmorGC,,将存活下来的对象存入幸存区。没进行以此minggc,对象的年龄就会增加一岁,当达到15之后就会被加入老年代。如果老年代内存不够,就会触发以此fullGC。
判断一个对象是否死亡可被清除?
主要有两种方式分别为程序计算法,当类被引用时就加一,当引用失效时减一。这种算法实现较为简单,但是当两个对象相互引用时,这两个对象就不会被清除。
第二种方式就是可达性分析
这个算法的基本思想就是通过一系列的称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的,需要被回收。
可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize
方法。当对象没有覆盖 finalize
方法,或 finalize
方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立关联,否则就会被真的回收。
然后gc算法分为
标记算法,标记复制、标记整理。根据不同区域使用不同的GC算法。
首先我们了解下创建类的过程,先加载然后连接最后对类属性进行初始化。
然后双亲委派机制就是指类载器加载类的一种过程。加载类可分为三种,bootstrapclassload、extensionclassload,appclassload。前两种分别加载%JAVA_HOME%/lib、%JAVA_HOME%/ext下面的jar包或者类。而appclassload主要加载当前应用下的类,一般只有我们自己实现的类。
在加载一个类时,首先会判断该类有没有在被前三种说的加载器加载,如果没有被前三种加载的话,就首先判断该类是否在bootstrapclassload、extensionclassload中,在的话直接加载,没在的话再使用appclassload加载。
优点:可以防止一个类被重复加载,双亲委派模型保证了 Java 程序的稳定运行,可以避免类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类),也保证了 Java 的核心 API 不被篡改。如果没有这种机制时,当我们创建一个jvm原有的类时,就会导致存在多个一个的类。