知识点:
1.JVM运行时数据区域以及内存溢出异常原因。
2.对象的创建过程。
1.JVM运行时数据区域以及内存溢出异常原因。
a.程序计数器
程序计数器是线程独有的,一个线程JVM会分配一个。它的作用是记录线程执行字节码的位置,我们知道对于单内核的系统,各个线程会不停的切换的,程序计数器会记录线程的执行位置。这个区域不会出现OutOfMemoryError的异常。
b.Java虚拟机栈
它也是线程私有的,它有两个作用,一是用来存储程序运行期间的基本数据类型和对象引用,二是它内部会有一个栈来存储方法的出入口信息,局部变量等,方法的调用到执行完成的过程就是栈帧出入栈的过程。这个区域会出先StackOverFlowError异常和OutOfMemoryError异常。
StackOverFlowError:线程请求的栈深度大于虚拟机所允许的深度,一般虚拟机都支持1000-2000,正常程序很难出现栈深度不够的情况。
OutOfMemoryError:线程在扩展栈时分配不到内存。
c.本地方法栈
它也是线程私有的,它的作用和Java虚拟机栈基本一样,唯一的不同点是Java虚拟机是执行Java方法服务,本地方法栈是使用Native服务。这个区域会出先StackOverFlowError异常和OutOfMemoryError异常。原因和Java虚拟机栈一样。
d.Java堆
它是所有线程共享的,它的作用是来存放对象实例,是垃圾收集器管理的主要区域。现在的垃圾收集器基本都是采用分代收集算法,所以堆又可细分为Eden空间,From Survivor空间,To Survivor空间等。这个区域会出现OutOfMemoryError异常,异常的原因是,如果堆中的对象都有用不能被垃圾收集器收集,但没有内存来存放新的对象。
e.方法区(包含运行时常量区)
它是所有线程共享的,它的作用是用来存储被虚拟机加载的类的信息,常量,静态变量等。这个区域会出现OutOfMemoryError异常,除了编译期间会将类信息存放到这个区域,运行期间也有一些方法可以动态存放信息到这个区域(String.intern()),当内存不够用时也会出现OutOfMemoryError异常。
f.直接内存(堆外内存)
这部分布式虚拟机运行时数据区的一部分,也不是Java虚拟机定义的内存区域。JDK1.4版本后NIO(New Input/Output)的这种IO方式,可以直接分配堆外内存,不通过堆内存来IO,当内存(这里就不是JVM内存的限制,而是操作系统内存的限制)不够用时也会出现OutOfMemoryError异常。
2.对象的创建过程。
加载过程如下:
a.检查类是否被加载(没有就先加载类)
b.为新对象分配内存
c.为对象初始化0值
d.设置对象的一些基本信息(那个类的实例,怎么找到类的原数据信息,对象的哈希码,对象GC分代年龄等)
e.执行对象的构造方法