Skip to content

java memory model

upan edited this page Jun 20, 2016 · 16 revisions

Java 内存模型

根据存储数据的不同,java内存通常被划分为5个区域:

  1. 程序计数器(Program Count Regster)
  2. 本地方法栈(NativStack)
  3. 方法区(Method Area)
  4. 栈 (Stack)
  5. 堆 (Heap)

程序计数器(Program Count Regster)

又叫程序寄存器。JVM支持多个线程同时运行,当每一个新线程被创建时,它都将得到它自己的PC寄存器(程序计数器)。如果现正正在执行的是一个Java方法(非native),那么PC寄存器的值总是指向吓一跳将被执行的指令,如果方法是native的吗,程序计数器的值不会被定义。JVM 的程序计数器的宽度足够保证可以持有一个返回地址或者native的指针。

栈(Stack)

相关启动参数:

  • -Xss 每个线程的栈大小

根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。一般小的应用,如果栈不是很深,应该是128k够用,大的应用建议使用256k。这个选项对性能影响比较大。

本地方法栈

方法区(Method Area)

相关启动参数

  • -XX:PermSize 设置Perm区的初始大小,默认物理内存的1/64
  • -XX:MaxPermSize 设置Perm区的最大值,物理内存的1/4

堆(Heap)

相关启动参数

  • -Xms 设置堆内存初始化大小,默认是物理内存的1/64但是小于1G
  • -Xmx 设置堆内存最大值,默认是物理内存的1/4但小于1G,服务器一般设置 -Xms、-Xmx相等以避免每次GC后调整堆的大小
  • -XX:MaxTenuringThreshold 设置对象在新生代中存活的次数,如果设置为0的话,则年清代对象不经过Survivor区,直接进入老年代。对于老年代比较多的应用可以提高效率。如果将此值设置为一个较大值,则年清代对象会在Survivor区进行多次复制,这样可以增加对像在年清代的存活时间,增加在年清代即呗回收的概率
  • -XX:PretenureSizeThreshold 设置超过指定大小的对象直接分配在老年代

堆-新生代 (Young Generation)

相关启动参数:

  • -Xmn设置新生代内存大小,增大年轻代后,将会减小老年代大小,此值对系统吸能影响较大,Sun 官方推荐配置为整个堆的3/8
  • -XX:SurvivorRatio 设置Eden与Survivor 空间的大小比例,这只为8,则两个Survivor区Survivor区与一个Eden区的比值为2:8,一个Survivor区栈整个年清代的1/10
  • -XX:NewRatio 年轻代(包括Eden和两个Survivor区)与老年代的壁纸(除去持久代),4 标识年清代与年老代的所占比值为1:4,年轻代占整个堆的1/5,Xms=Xmx 并且设置了Xmn的情况下,该参数不需要设置

堆-老年代(Old Generation)

当Old区控件不够时,JVM会在Old区进行major collection,完成垃圾收集后,若Survivor及 Old区任然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现“Out of memory错误”

Clone this wiki locally