JVM运行时内存空间结构

JVM执行Java程序的过程中管理的内存空间,包括下列几个区域:

程序计数器(Program CounterRegister)

·        线程私有,占用空间很小。

·        线程所执行代码行号指示器。

·        解释器通过计数器的值选择下一条执行的字节码指令。

·        线程执行Native方法时值为空。

·        没有OOM(OutOfMemory)。Java虚拟机栈(Java Virtual Machine Stacks)

·        线程私有。·        储存方法栈帧(Stack Frame)。

    ·        栈帧:储存局部变量表、操作栈、动态链接、方法出口等。

    ·        局部变量表:编译器可知的基本类型、对象引用和returnAddress(字节码指令的地址)。在编译期间完成分配,运行时大小不变。

·        存在StackOverflowError和OOM。

    ·        StackOverflowError:线程请求栈深度大于VM允许深度。

    ·        OOM:创建线程或扩展线程空间时无足够内存。

StackOverflowError例子:

/**
- Xss256k
*
@author  Alfred Xu <bjxufeng@360buy.com>
*
*/
public   class  StackSOF {
    int   recursionLength ;
    void  recusion() {
       recursionLength ++;
      recusion();
   }
    public   static   void  main(String[] args) {
      StackSOF sof =  new  StackSOF();
       try  {
        sof.recusion();
      }  catch  (Throwable e) {
        System. out .println(sof. recursionLength );
        e.printStackTrace();
      }
   }
}

OOM例子:

/**
- Xss2m
*
@author  Alfred Xu <bjxufeng@360buy.com>
*
*/
public   class  StackOOM {
    static   class  Tester  extends  Thread {
       @Override
       public   void  run() {
         try  {
           Thread.sleep(1000 * 1000);
        }  catch  (InterruptedException e) {
           e.printStackTrace();
        }
      }
   }
    public   static   void  main(String[] args) {
       for  ( int  i = 0;; i++) {
         new  Tester().start();
        System. out .println(i);
      }
   }
}


本地方法栈(Native MethodStacks)

·        线程私有,类似虚拟机栈。

·        服务Native方法。

·        同样存在StackOverflowError和OOM。

·        Hotspot中将Java虚拟机栈和本地方法栈合二为一,通过-Xss设置大小。JDK1.6以前默认256K,1.6默认1M。

Java堆(Java Heap)

·        所有线程共享。

·        储存对象实例。

·        GC和OOM的主要区域。

Heap OOM例子:

/**
- Xms10m  - Xmx10m
*
@author  Alfred Xu <bjxufeng@360buy.com>
*
*/
public   class  HeapOOM {
    public   static   void  main(String[] args) {
      List<Long> list =  new  ArrayList<Long>();
       for  ( long  i = 0;; i++) {
        list.add(i);
        System. out .println(i);
      }
   }
}

方法区(Method Area)

·        又叫非堆(Non-Heap),对应HotSpot的永久代(Permanent Generation)。

·        所有线程共享。

·        储存VM加载的类信息、常量、静态变量、JIT编译代码等。

·        也有OOM,一般是由于大量使用反射生成class。

·        包含运行时常量池(Rumtime ConstantPool)。

常量池溢出例子:

/**
- XX:MaxPermSize=1m
*
@author  Alfred Xu <bjxufeng@360buy.com>
*
*/
public   class  ConstantPoolOOM {
    public   static   void  main(String[] args) {
      List<String> list =  new  ArrayList<String>();
       for  ( int  i = 0;; i++) {
        list.add(String.valueOf(i).intern());
        System. out .println(i);
      }
   }
}

本机直接内存(Direct Memory)

·        不受VM直接管理,但也有OOM。

·        和NIO中的DirectByteBuffer相关。

·        默认和Java堆大小一致。

例子:

/**
- XX:MaxDirectMemorySize=10m
*
@author  Alfred Xu <bjxufeng@360buy.com>
*
*/
@SuppressWarnings ( "restriction" )
public   class  DirectMemoryOOM {
    static   final   int   _1MB  = 1024 * 1024;
    static   void  unsafeAllocate()  throws  IllegalArgumentException,
        IllegalAccessException {
      Field unsafeField = Unsafe. class .getDeclaredFields()[0];
      unsafeField.setAccessible( true );
      Unsafe unsafe = (Unsafe) unsafeField.get( null );
      List<Long> list =  new  ArrayList<Long>();
       for  ( int  i = 0;; i++) {
         long  l = unsafe.allocateMemory( _1MB );
        list.add(l);
        System. out .println(i);
      }
   }
    static   void  byteBufferAllocate( boolean  direct) {
      List<ByteBuffer> list =  new  ArrayList<ByteBuffer>();
       for  ( int  i = 0;; i++) {
        ByteBuffer bb;
         if  (direct) {
           bb = ByteBuffer.allocateDirect( _1MB );
        }  else  {
           bb = ByteBuffer.allocate( _1MB );
        }
        list.add(bb);
        System. out .println(i);
      }
   }
    public   static   void  main(String[] args)  throws  IllegalArgumentException,
        IllegalAccessException {
      byteBufferAllocate( true );
       // unsafeAllocate();
   }
}

Hotspot Java内存空间结构



新生代(Young Generation)

大部分的对象的内存分配和回收在这里完成。

Eden

新建的对象分配在此,minor GC后被清空。

Survivor

存储至少经过一次GC存活下来的对象,以增大该对象在提升至老生代前被回收的机会。

From Space

在minor GC后被清空,GC后存活的对象放入老生代。

To Space

Eden中在新生代GC后存活的对象放在此。

老生代(Old Generation)

多次GC后存活的对象或者新生代放置不下的大对象。

永生代(PermanentGeneration)

方法区。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值