Java 内存区域与内存溢出

Java 内存区域可以分为两大类:

1、线程共享的:
方法区:线程共享;用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译的代码等数据。它被虚拟机规范描述为堆的一部分。也被视为“永久代”。

运行时常量:方法区的一部分;

堆(heap):所以线程共用;几乎所有的对象实例、数组都是在堆上分配内存(JIT技术可以不在堆上分配内存、比如栈);可以物理不连续;可能存在给各线程分配的,线程私有的线程缓冲区(Thread Local
Allocation Buffer, TLAB);堆通车也被分为初生代,年老代;

执行引擎:

本地接口库:

直接内存:非虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域,也可能导致内存异常;里面的内存为堆外内存。

 

2、线程独享的:
虚拟机栈:生命周期和线程相同;其中的局部变量表保存基础类型数据或者对象的引用;如果线程请求的栈深度超过了虚拟机运行的深度,就会抛出StackOverMemoryError;

本地方法栈:和虚拟机栈类似,甚至有些虚拟机上面并没有区分这两者。

程序计算器:当前线程执行字节码的行号指示器,被字节码解释器用于选择下一条执行指令。占用内存小,只用于java代码。

 

对象内存布局:

1、对象:由三部分组成,对象头(Header)、实例数据(Instance data)、对齐填充(padding)

2、对象头部:
a、一部分用于存储自身运行时数据,包括哈希码(25bit)、GC分代年龄(4bit)、锁状态标记(2bit)、线程持有的锁、偏向线程ID、偏向时间戳;
b、一部分为类型指针,指向它的类元数据

 

posted @ 2016-09-04 11:44  lipeil  阅读(228)  评论(0编辑  收藏  举报