内存区域:
1. java 堆:对象实例,线程共享,垃圾收集器管理的主要区域
2.方法区:类信息、常量、静态变量、即时编译器编译后的代码数据等
3.程序计数器:当前线程所执行的字节码行号指示器,线程私有
4.java虚拟机栈:方法执行时创建栈帧(用于存储局部变量表、操作数栈、动态链接、方法出口等信息),方法调用到执行完成,对应一个栈帧的入栈和出栈过程
5.本地方法栈(Native方法)
对象的创建
1. 类加载->2.为新生对象分配内存->3.内存空间初始化为零值->4.对象设置(类型信息、如何找到类的元数据信息、对象哈希码、对象GC分代年龄等信息)->5.对象初始化
对象的内存布局:分为3块区域:对象头(包括2部分,1.对象运行时数据,如哈希码、GC分代年龄、锁和线程的相关信息,2.类型指针,即指向类元数据的指针)、对象存储的信息、对齐填充信息
内存异常的发生情况
1.java堆溢出:java堆用于存储对象,不断创建对象且GC roots到对象之间可达,如:p.51
-Xmx最大堆大小-Xms最小堆大小
2.虚拟机栈和本地方法栈溢出:
1).-Xss设置栈容量,
2)单线程下:定义大量局部变量,增大方法中的本地变量表长度,使得栈帧太大。如可递归无结束的调用方法
多线程下:建立过多线程
3.方法区和运行时常量池溢出
1).常量池溢出
2)方法区用于存放class相关信息,只需要大量产生类,直到溢出。如:动态类(反射、动态代理)的大量生成
4.本机直接内存溢出
可通过-XX指定,默认与java堆的最大值(-Xmx指定)一样
使用NIO时,需要考虑到直接内存的大小。