Java JVM(一):内存结构 和 相关内存参数

来源:互联网 发布:微星 主机 知乎 编辑:程序博客网 时间:2024/06/14 14:15

包括:

一. Java 整体内存结构

二. Java 堆内存结构

三. Java 堆内存和非堆内存参数


一. Java 整体内存结构

以下针对JDK7:


如图,JVM内存区域分为PC寄存器,JVM方法栈,本地方法栈,JVM方法区,JVM堆。
  • PC寄存器:存放下一条指令在方法中的偏移量。也可以看做是线程所执行的字节码的行号指示器,字节码解释器的工作就是通过改变这个计数器的值来选取下一条需要执行的指令。
  • JVM方法栈:PC寄存器,JVM方法栈,和本地方法栈都是线程私有。在JVM方法栈有,有局部变量区和操作数区。人们经常说的JVM内存分为堆内存和栈内存(这 是一个比较笼统的说法)中的栈内存也就是指这个JVM方法栈的内存。当线程请求的栈的深度大于虚拟机所允许的深度时,就会抛出StackOverFlow 异常;如果虚拟机栈可以动态扩展,当扩展的时候无法申请足够的内存,会抛出OutOfMemory异常。
  • 本地方法栈:主要用来支持native方法,记录native方法调用的状态。可以把native 方法看成是 java 调用 非 java 代码的一个接口。主要用于允许Java 和其他语言,比如 C 语言进行交互。
  • JVM方法区:主要存储已经加载的类的信息,比如构造函数的信息,方法的信息,常量的信息。Class对象提供的getXXX()方法取得的类的信息就是从JVM方法区中得到。也是永生代所在的地方。
  • JVM堆:主要目的是用来存放数组和对象。同时,JVM 堆也是 内存溢出和垃圾回收的主要区域。


二. Java 堆内存结构


如图所示,在JVM堆中,又分为新生代,老生代。

        可以看到,新生代中,又分为eden区域和两个Survivor区域。(由于回收机制采用复制算法,所以这样分,可看另一篇垃圾收集博文)默认比例为8:1:1,也就是说,可以用的内存为90%(另一篇垃圾收集博文说有为什么),当然,可以用-XX:SurvivorRatio设置eden和Survivor的比值,默认为8:1。

        特别注意:最右侧的永久代在JDK8中已经不在存在,被元空间代替metaspace所代替。另外,在jdk7中,字符串内部池就已经从永久代中移除。


三. Java 堆内存和非堆内存参数

  •  -XX:Persize:设置非堆内存初始值,默认为1/64。
  • -XX:MaxPersize:设置非堆内存最大值,默认为1/4.
  • -Xss:设置每个线程占用堆内存大小,现在默认为1M,以前为256K。设置线程越小,堆内存大小不变,可以创造的线程数越多(当然有一个限度)。但是这个值也需要经过严格的测试再设置。
  • -Xms:JVM堆初始分配内存。默认为物理内存的1/64,当默认堆内存的空余空间小于40%的时候,这个堆内存就会自动增长到-Xmx指定的最大堆分配内存。
  • -Xmx :JVM的最大堆分配内存。默认为物理内存的1/4,当空余内存大于70%的时候,该堆内存又会自动减少到-Xms指定的内存。
  • -Xmn:指定新生代的内存大小。当堆大小不变的情况下,新生代越大,老生代越小,默认新生代和老年代的比例为1:2,而且这个比例会严重影响系统性能,sun推荐为新生代占整个堆内存3/8。
  • -XX:SurvivorRatio:新生代中,又分为eden区域和两个Survivor区域。默认比例为8:1:1,也就是说,可以用的内存为90%。该参数用来设置eden和Survivor的比值,默认为8:1。


0 0
原创粉丝点击