JVM运行时内存空间结构
2013-05-24 11:32
441 查看
JVM执行Java程序的过程中管理的内存空间,包括下列几个区域:
程序计数器(Program CounterRegister)
· 线程私有,占用空间很小。
· 线程所执行代码行号指示器。
· 解释器通过计数器的值选择下一条执行的字节码指令。
· 线程执行Native方法时值为空。
· 没有OOM(OutOfMemory)。Java虚拟机栈(Java
Virtual Machine Stacks)
· 线程私有。· 储存方法栈帧(Stack
Frame)。
· 栈帧:储存局部变量表、操作栈、动态链接、方法出口等。
· 局部变量表:编译器可知的基本类型、对象引用和returnAddress(字节码指令的地址)。在编译期间完成分配,运行时大小不变。
· 存在StackOverflowError和OOM。
· StackOverflowError:线程请求栈深度大于VM允许深度。
· OOM:创建线程或扩展线程空间时无足够内存。
StackOverflowError例子:
[align=left]/**[/align]
[align=left]* -Xss256k[/align]
[align=left]*[/align]
[align=left]* @author Alfred Xu <bjxufeng@360buy.com>[/align]
[align=left]*[/align]
[align=left]*/[/align]
public class StackSOF
{
[align=left] int recursionLength;[/align]
[align=left][/align]
void recusion()
{
[align=left] recursionLength++;[/align]
[align=left] recusion();[/align]
[align=left] }[/align]
[align=left][/align]
public static void main(String[]
args) {
[align=left] StackSOF sof = new StackSOF();[/align]
[align=left] try {[/align]
[align=left] sof.recusion();[/align]
} catch (Throwable
e) {
[align=left] System.out.println(sof.recursionLength);[/align]
[align=left] e.printStackTrace();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
OOM例子:
[align=left]/**[/align]
[align=left]* -Xss2m[/align]
[align=left]*[/align]
[align=left]* @author Alfred Xu <bjxufeng@360buy.com>[/align]
[align=left]*[/align]
[align=left]*/[/align]
public class StackOOM
{
static class Tester extends Thread
{
[align=left] @Override[/align]
public void run()
{
[align=left] try {[/align]
Thread.sleep(1000
* 1000);
} catch (InterruptedException
e) {
[align=left] e.printStackTrace();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left][/align]
public static void main(String[]
args) {
for (int i
= 0;; i++) {
[align=left] new Tester().start();[/align]
[align=left] System.out.println(i);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
本地方法栈(Native MethodStacks)
· 线程私有,类似虚拟机栈。
· 服务Native方法。
· 同样存在StackOverflowError和OOM。
· Hotspot中将Java虚拟机栈和本地方法栈合二为一,通过-Xss设置大小。JDK1.6以前默认256K,1.6默认1M。
Java堆(Java Heap)
· 所有线程共享。
· 储存对象实例。
· GC和OOM的主要区域。
Heap OOM例子:
[align=left]/**[/align]
[align=left]* -Xms10m -Xmx10m[/align]
[align=left]*[/align]
[align=left]* @author Alfred Xu <bjxufeng@360buy.com>[/align]
[align=left]*[/align]
[align=left]*/[/align]
[align=left]public class HeapOOM {[/align]
public static void main(String[]
args) {
List<Long> list
= new ArrayList<Long>();
for (long i
= 0;; i++) {
[align=left] list.add(i);[/align]
[align=left] System.out.println(i);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
方法区(Method Area)
· 又叫非堆(Non-Heap),对应HotSpot的永久代(Permanent
Generation)。
· 所有线程共享。
· 储存VM加载的类信息、常量、静态变量、JIT编译代码等。
· 也有OOM,一般是由于大量使用反射生成class。
· 包含运行时常量池(Rumtime ConstantPool)。
常量池溢出例子:
[align=left]/**[/align]
[align=left]* -XX:MaxPermSize=1m[/align]
[align=left]*[/align]
[align=left]* @author Alfred Xu <bjxufeng@360buy.com>[/align]
[align=left]*[/align]
[align=left]*/[/align]
public class ConstantPoolOOM
{
public static void main(String[]
args) {
List<String> list
= new ArrayList<String>();
for (int i
= 0;; i++) {
[align=left] list.add(String.valueOf(i).intern());[/align]
[align=left] System.out.println(i);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
本机直接内存(Direct Memory)
· 不受VM直接管理,但也有OOM。
· 和NIO中的DirectByteBuffer相关。
· 默认和Java堆大小一致。
例子:
[align=left]/**[/align]
[align=left]* -XX:MaxDirectMemorySize=10m[/align]
[align=left]*[/align]
[align=left]* @author Alfred Xu <bjxufeng@360buy.com>[/align]
[align=left]*[/align]
[align=left]*/[/align]
[align=left]@SuppressWarnings("restriction")[/align]
public class DirectMemoryOOM
{
static final int _1MB =
1024 * 1024;
[align=left][/align]
[align=left] static void unsafeAllocate() throws IllegalArgumentException,[/align]
IllegalAccessException
{
Field unsafeField
= Unsafe.class.getDeclaredFields()[0];
[align=left] unsafeField.setAccessible(true);[/align]
Unsafe unsafe =
(Unsafe) unsafeField.get(null);
List<Long> list
= new ArrayList<Long>();
for (int i
= 0;; i++) {
long l
= unsafe.allocateMemory(_1MB);
[align=left] list.add(l);[/align]
[align=left] System.out.println(i);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left][/align]
static void byteBufferAllocate(boolean direct)
{
List<ByteBuffer>
list = new ArrayList<ByteBuffer>();
for (int i
= 0;; i++) {
[align=left] ByteBuffer bb;[/align]
if (direct)
{
[align=left] bb = ByteBuffer.allocateDirect(_1MB);[/align]
[align=left] } else {[/align]
[align=left] bb = ByteBuffer.allocate(_1MB);[/align]
[align=left] }[/align]
[align=left] list.add(bb);[/align]
[align=left] System.out.println(i);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left][/align]
public static void main(String[]
args) throws IllegalArgumentException,
IllegalAccessException
{
[align=left] byteBufferAllocate(true);[/align]
//
unsafeAllocate();
[align=left] }[/align]
[align=left]}[/align]
Hotspot Java内存空间结构
新生代(Young Generation)
大部分的对象的内存分配和回收在这里完成。
Eden
新建的对象分配在此,minor GC后被清空。
Survivor
存储至少经过一次GC存活下来的对象,以增大该对象在提升至老生代前被回收的机会。
From Space
在minor GC后被清空,GC后存活的对象放入老生代。
To Space
Eden中在新生代GC后存活的对象放在此。
老生代(Old Generation)
多次GC后存活的对象或者新生代放置不下的大对象。
永生代(PermanentGeneration)
方法区。
程序计数器(Program CounterRegister)
· 线程私有,占用空间很小。
· 线程所执行代码行号指示器。
· 解释器通过计数器的值选择下一条执行的字节码指令。
· 线程执行Native方法时值为空。
· 没有OOM(OutOfMemory)。Java虚拟机栈(Java
Virtual Machine Stacks)
· 线程私有。· 储存方法栈帧(Stack
Frame)。
· 栈帧:储存局部变量表、操作栈、动态链接、方法出口等。
· 局部变量表:编译器可知的基本类型、对象引用和returnAddress(字节码指令的地址)。在编译期间完成分配,运行时大小不变。
· 存在StackOverflowError和OOM。
· StackOverflowError:线程请求栈深度大于VM允许深度。
· OOM:创建线程或扩展线程空间时无足够内存。
StackOverflowError例子:
[align=left]/**[/align]
[align=left]* -Xss256k[/align]
[align=left]*[/align]
[align=left]* @author Alfred Xu <bjxufeng@360buy.com>[/align]
[align=left]*[/align]
[align=left]*/[/align]
public class StackSOF
{
[align=left] int recursionLength;[/align]
[align=left][/align]
void recusion()
{
[align=left] recursionLength++;[/align]
[align=left] recusion();[/align]
[align=left] }[/align]
[align=left][/align]
public static void main(String[]
args) {
[align=left] StackSOF sof = new StackSOF();[/align]
[align=left] try {[/align]
[align=left] sof.recusion();[/align]
} catch (Throwable
e) {
[align=left] System.out.println(sof.recursionLength);[/align]
[align=left] e.printStackTrace();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
OOM例子:
[align=left]/**[/align]
[align=left]* -Xss2m[/align]
[align=left]*[/align]
[align=left]* @author Alfred Xu <bjxufeng@360buy.com>[/align]
[align=left]*[/align]
[align=left]*/[/align]
public class StackOOM
{
static class Tester extends Thread
{
[align=left] @Override[/align]
public void run()
{
[align=left] try {[/align]
Thread.sleep(1000
* 1000);
} catch (InterruptedException
e) {
[align=left] e.printStackTrace();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left][/align]
public static void main(String[]
args) {
for (int i
= 0;; i++) {
[align=left] new Tester().start();[/align]
[align=left] System.out.println(i);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
本地方法栈(Native MethodStacks)
· 线程私有,类似虚拟机栈。
· 服务Native方法。
· 同样存在StackOverflowError和OOM。
· Hotspot中将Java虚拟机栈和本地方法栈合二为一,通过-Xss设置大小。JDK1.6以前默认256K,1.6默认1M。
Java堆(Java Heap)
· 所有线程共享。
· 储存对象实例。
· GC和OOM的主要区域。
Heap OOM例子:
[align=left]/**[/align]
[align=left]* -Xms10m -Xmx10m[/align]
[align=left]*[/align]
[align=left]* @author Alfred Xu <bjxufeng@360buy.com>[/align]
[align=left]*[/align]
[align=left]*/[/align]
[align=left]public class HeapOOM {[/align]
public static void main(String[]
args) {
List<Long> list
= new ArrayList<Long>();
for (long i
= 0;; i++) {
[align=left] list.add(i);[/align]
[align=left] System.out.println(i);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
方法区(Method Area)
· 又叫非堆(Non-Heap),对应HotSpot的永久代(Permanent
Generation)。
· 所有线程共享。
· 储存VM加载的类信息、常量、静态变量、JIT编译代码等。
· 也有OOM,一般是由于大量使用反射生成class。
· 包含运行时常量池(Rumtime ConstantPool)。
常量池溢出例子:
[align=left]/**[/align]
[align=left]* -XX:MaxPermSize=1m[/align]
[align=left]*[/align]
[align=left]* @author Alfred Xu <bjxufeng@360buy.com>[/align]
[align=left]*[/align]
[align=left]*/[/align]
public class ConstantPoolOOM
{
public static void main(String[]
args) {
List<String> list
= new ArrayList<String>();
for (int i
= 0;; i++) {
[align=left] list.add(String.valueOf(i).intern());[/align]
[align=left] System.out.println(i);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
本机直接内存(Direct Memory)
· 不受VM直接管理,但也有OOM。
· 和NIO中的DirectByteBuffer相关。
· 默认和Java堆大小一致。
例子:
[align=left]/**[/align]
[align=left]* -XX:MaxDirectMemorySize=10m[/align]
[align=left]*[/align]
[align=left]* @author Alfred Xu <bjxufeng@360buy.com>[/align]
[align=left]*[/align]
[align=left]*/[/align]
[align=left]@SuppressWarnings("restriction")[/align]
public class DirectMemoryOOM
{
static final int _1MB =
1024 * 1024;
[align=left][/align]
[align=left] static void unsafeAllocate() throws IllegalArgumentException,[/align]
IllegalAccessException
{
Field unsafeField
= Unsafe.class.getDeclaredFields()[0];
[align=left] unsafeField.setAccessible(true);[/align]
Unsafe unsafe =
(Unsafe) unsafeField.get(null);
List<Long> list
= new ArrayList<Long>();
for (int i
= 0;; i++) {
long l
= unsafe.allocateMemory(_1MB);
[align=left] list.add(l);[/align]
[align=left] System.out.println(i);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left][/align]
static void byteBufferAllocate(boolean direct)
{
List<ByteBuffer>
list = new ArrayList<ByteBuffer>();
for (int i
= 0;; i++) {
[align=left] ByteBuffer bb;[/align]
if (direct)
{
[align=left] bb = ByteBuffer.allocateDirect(_1MB);[/align]
[align=left] } else {[/align]
[align=left] bb = ByteBuffer.allocate(_1MB);[/align]
[align=left] }[/align]
[align=left] list.add(bb);[/align]
[align=left] System.out.println(i);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left][/align]
public static void main(String[]
args) throws IllegalArgumentException,
IllegalAccessException
{
[align=left] byteBufferAllocate(true);[/align]
//
unsafeAllocate();
[align=left] }[/align]
[align=left]}[/align]
Hotspot Java内存空间结构
新生代(Young Generation)
大部分的对象的内存分配和回收在这里完成。
Eden
新建的对象分配在此,minor GC后被清空。
Survivor
存储至少经过一次GC存活下来的对象,以增大该对象在提升至老生代前被回收的机会。
From Space
在minor GC后被清空,GC后存活的对象放入老生代。
To Space
Eden中在新生代GC后存活的对象放在此。
老生代(Old Generation)
多次GC后存活的对象或者新生代放置不下的大对象。
永生代(PermanentGeneration)
方法区。
相关文章推荐
- JVM内存结构(运行时数据区)
- JVM运行时的内存结构
- jvm-运行时内存结构
- Jvm内存空间结构是什么样的?
- JVM的运行时内存结构
- JVM内存结构——运行时数据区
- JVM学习记录-JVM的内存结构管理和运行时数据区理解
- jvm - 运行时内存结构
- Jvm内存空间结构是什么样的?
- 【Java】关于JVM运行时内存空间、JVM垃圾回收机制
- jvm - 运行时内存结构
- JVM运行时内存结构
- Simple Java—Compiler and JVM(一)Java对象运行时的内存结构
- [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义
- 【001】【JVM——运行时内存结构】
- jvm - 运行时内存结构
- JVM运行时内存结构
- Java 虚拟机(JVM)运行时内存结构
- 深入理解JVM____JVM运行时内存结构
- JVM 运行时内存结构