-
java虚拟机有很多款。HotSpot是最流行的
-
hotspot虚拟机内存结构
栈,堆,方法区,本地方法栈,程序计数器 -
栈
栈就是执行方法的内存区域,方法的执行时压栈,执行结束弹栈
java支持多线程,有多个栈。
栈满错误StackOverflowError
-
堆
堆内存种开辟对象的空间,存储真正的数据,栈方法里定义的变量只是一个引用,指向堆里对象数据。
jdk1.6里,堆分为新生区(伊甸园),幸存区1,幸存区2,老年区,永久区。Class对象在方法区里。jdk1.8后,没有永久区了,加了一个非堆区,非堆区里存放Class对象和静态常量(常量池)
垃圾回收,回收的就是堆里没有被引用的对象。
堆可以进行调优,设置堆内存的空间分配
OOM错误。 OutOfMemory,就是堆满异常
5 方法区
类加载器将.class文件加载到方法区。1.6里方法区存也存常量和Class对象。1.8之后常量和Class对象都存到堆的非堆区了。
Class对象是new对象时获取数据的交互接口,每个.class文件加载完毕后都会有一个Class对象
-
本地方法栈,native修饰的方法入栈就入到本地方法栈里。最初设计是为了兼容c和c++。
-
程序计数器
程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
每条线程都需要有一个独立的程序计数器
7. 类加载器,双亲委派机制
类加载器有三个,BootStrapClassLoader,ExtClassLoader,AppClassLoader。
三个类是继承关系,AppClassLoader是最低的子类
BootStrapClassLoader:加载lib/rt.jar里的API,就是java的核心API
ExtClassLoader:加载lib/ext/下的API
AppClassLoader:加载当前web引用的API
双亲委派机制
AppClassLoader,ExtClassLoader,BootStrapClassLoader。
AppClassLoader是最低的子类,但是类首先不是它加载的,向上委托到BootStrapClassLoader先加载,BootStrapClassLoader加载不到在回到子类加载。
好处:保证原来java提供的API的安全性,BootStrapClassLoader先加载rt.jar。防止AppClassLoader在应用里加载到重名的。
创建一个对象的过程
类加载器加载Student.class, 堆的非堆区创建Class对象。栈方法new,从非堆的Class对象获取Student属性数据,在堆里开辟内存空间。初始化赋值。把堆的内存地址值赋到栈方法的引用。就是首图中红线的流程。
8. 垃圾回收机制
垃圾回收就是清空堆内存里不被引用的对象数据。归还内存空间。
java又称为c+±-,–指的就是摒弃了c++的指针,原因就是有垃圾回收机制,不需要释放指针,不被引用的对象又垃圾回收机制释放。
GC算法:
复制算法
标记删除算法