JVM之概念了解
堆
- 堆用于存储创建好的对象和数组
- jvm只有一个堆,被所有线程共享
- 堆是一个连续的内部空间,内存分配灵活
栈
- 栈描述的是方法执行的内存模型,每个方法被调用都会创建一个栈帧(即存储局部变量、操作数、方法出口等的地方)
- jvm为每个线程创建一个栈(main),用于存放该线程执行方法的信息(实际参数、局部变量等)
- 栈属于线程私有,不能实现线程间的共享
- 存储属性(先进先出,后进先出)
- 栈是系统自动分配,连续的内存空间
元空间
由于方法区主要存储类的相关信息,所以对于动态生成类的情况比较容易出现永久代的内存溢出,所有java8 将方法区从堆空间中挪出,将类元数据放到本地内存中。
类加载器
定义:
类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因。在类加载的第一阶段“加载”过程中,需要通过一个类的全限定名来获取定义此类的二进制字节流,完成这个动作的代码块就是类加载器。这一动作是放在Java虚拟机外部去实现的,以便让应用程序自己决定如何获取所需的类。
1.启动类(或根类)加载器(Bootstrap ClassLoader):
这个加载器不是一个Java类,而是由底层的c++实现,负责将存放在JAVA_HOME下lib目录中的类库,比如rt.jar。因此,启动类加载器不属于Java类库,无法被Java程序直接引用。
2.扩展类加载器(ExtClassLoader):
负责加载JAVA_HOME下lib\ext目录下的,或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可以直接使用扩展类加载器。
3.应用类加载器(AppClassLoader):
由于这个类加载器是ClassLoader中的getSystemClassLoader方法的返回值,所以也叫系统类加载器。它负责加载用户类路径上所指定的类库,可以被直接使用。如果未自定义类加载器,默认为该类加载器。
双亲委派模型
定义:当一个类加载器接收到类加载请求时,会先请求其父类加载器加载,依次递归,当父类加载器无法找到该类时(根据类的全限定名称),子类加载器才会尝试去加载。
意义:双亲委派模型是为了保证Java核心库的类型安全(如在程序中自定义一个java.lang.String是不会被应用的)。所有Java应用都至少需要引用java.lang.Object类,通过双亲委派模型,对于Java核心库的类的加载工作由启动类加载器来统一完成,保证了Java应用所使用的都是同一个版本的Java核心库的类,是互相兼容的。