java内存结构主要有三大块:堆内存(heap)、方法区和栈(stack)。
堆内存是是JVM中最大的一块由年轻代和老年代组成,年轻代又被分成三部分,Eden空间、FromSurvivor空间、ToSurvivor空间,默认是按照8:1:1的比例来分配。
方法区存储类信息、常量、静态变量等数据,是线程共享区域。
栈分为java虚拟机栈和本地方法栈主要用于方法的执行。
对内存的控制参数设置:
a、-Xms设置堆的最小空间大小。
b、-Xmx设置堆的最大空间大小。
c、-XX:NewSize设置新生代最小空间大小。
d、-XX:MaxNewSize设置新生代最大空间大小。
e、-XX:PermSize设置持久代最小空间大小。
f、-XX:MaxPermSize设置持久代最大空间大小。
g、Xss设置每个线程的堆栈大小。
没有设置老年代的参数,但是可以设置堆空间大小和新生代空间大小两个参数来间接控制年老代的大小。
根据:老年代空间 = 堆空间 - 年轻代空间。
方法区和堆是所有线程共享的内存区域,java栈、本地方法和程序员计数器试运行时线程私有的内存区域。
堆(Heap):对于大多数应用来说,堆是JVM所管理的内存中最大的一块,堆是被所有线程共享的一块内存区域,java堆在虚拟机启动时候创建。堆内存的唯一目的就是存放对象实例,几乎所有的对象实例都在这里进行分配内存。
堆是垃圾回收器管理的主要区域,因此很多时候也被称作“GC堆”。从内存回收的角度来看,由于现在收集器基本都是采用的分代收集算法,所以java堆中还可以细分为:新生代和老年代,再细致一点年轻代可以分为:Eden空间、FromSurvivor空间、ToSurvivor空间。
当前主流的虚拟机都是按照可扩展来实现的(通过-Xms和-Xmx)。当堆中没有内存可以分配时,并且堆也无法在进行扩展时候,将会抛出OutOfMemoryError异常。
方法区:与java堆一样,是各个线程的共享内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译过后的代码等数据。
程序计数器:是一块较小的内存空间,它的作用可以看作是当前线程所执行字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的位置,每条线程都需要一个独立的程序计数器,再各个线程之间的计数器是互不影响的,独立存储,这类内存区域为“线程私有”的内存。
栈(Stack):与程序计数器一样是线程私有的,栈的生命周期与线程相同。
虚拟机栈是指java方法执行的内存模型,每个方法执行的时候都会同时创建一个栈帧(Stack Frame),用于存储局部变量表、操作栈、动态链接、方法出口等信息。每个方法被调用直到执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
本地方法栈(Native):与虚拟机栈发挥的作用相似,但是虚拟机栈是为虚拟机执行java方法服务,本地方法栈则是为虚拟机使用到Native方法服务。
java堆中的各代分布:
1.年轻代
年轻代分为三个区域:一个Eden区,两个Survivor区。大部分对象在Eden区中生成,当Eden区满时,还存活的对象将被复制到Survivor区,当这个Survivor区满时,此区的存活对象将被复制到另一个Survivor区,当第二个Suevivor区也满了的时候,从第一个Survivor复制过来的且还存活的对象将被复制到老年区。
2.老年代
老年代存放从年轻代存活的对象。一般来说老年代里存放的对象生命周期都比较长。
3.持久代
用于存放静态文件,如java类、方法等。持久代对来及回收没有显著影响。
通常意义上的JVM内存回收总是指堆内存回收。
堆内存是是JVM中最大的一块由年轻代和老年代组成,年轻代又被分成三部分,Eden空间、FromSurvivor空间、ToSurvivor空间,默认是按照8:1:1的比例来分配。
方法区存储类信息、常量、静态变量等数据,是线程共享区域。
栈分为java虚拟机栈和本地方法栈主要用于方法的执行。
对内存的控制参数设置:
a、-Xms设置堆的最小空间大小。
b、-Xmx设置堆的最大空间大小。
c、-XX:NewSize设置新生代最小空间大小。
d、-XX:MaxNewSize设置新生代最大空间大小。
e、-XX:PermSize设置持久代最小空间大小。
f、-XX:MaxPermSize设置持久代最大空间大小。
g、Xss设置每个线程的堆栈大小。
没有设置老年代的参数,但是可以设置堆空间大小和新生代空间大小两个参数来间接控制年老代的大小。
根据:老年代空间 = 堆空间 - 年轻代空间。
方法区和堆是所有线程共享的内存区域,java栈、本地方法和程序员计数器试运行时线程私有的内存区域。
堆(Heap):对于大多数应用来说,堆是JVM所管理的内存中最大的一块,堆是被所有线程共享的一块内存区域,java堆在虚拟机启动时候创建。堆内存的唯一目的就是存放对象实例,几乎所有的对象实例都在这里进行分配内存。
堆是垃圾回收器管理的主要区域,因此很多时候也被称作“GC堆”。从内存回收的角度来看,由于现在收集器基本都是采用的分代收集算法,所以java堆中还可以细分为:新生代和老年代,再细致一点年轻代可以分为:Eden空间、FromSurvivor空间、ToSurvivor空间。
当前主流的虚拟机都是按照可扩展来实现的(通过-Xms和-Xmx)。当堆中没有内存可以分配时,并且堆也无法在进行扩展时候,将会抛出OutOfMemoryError异常。
方法区:与java堆一样,是各个线程的共享内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译过后的代码等数据。
程序计数器:是一块较小的内存空间,它的作用可以看作是当前线程所执行字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的位置,每条线程都需要一个独立的程序计数器,再各个线程之间的计数器是互不影响的,独立存储,这类内存区域为“线程私有”的内存。
栈(Stack):与程序计数器一样是线程私有的,栈的生命周期与线程相同。
虚拟机栈是指java方法执行的内存模型,每个方法执行的时候都会同时创建一个栈帧(Stack Frame),用于存储局部变量表、操作栈、动态链接、方法出口等信息。每个方法被调用直到执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
本地方法栈(Native):与虚拟机栈发挥的作用相似,但是虚拟机栈是为虚拟机执行java方法服务,本地方法栈则是为虚拟机使用到Native方法服务。
java堆中的各代分布:
1.年轻代
年轻代分为三个区域:一个Eden区,两个Survivor区。大部分对象在Eden区中生成,当Eden区满时,还存活的对象将被复制到Survivor区,当这个Survivor区满时,此区的存活对象将被复制到另一个Survivor区,当第二个Suevivor区也满了的时候,从第一个Survivor复制过来的且还存活的对象将被复制到老年区。
2.老年代
老年代存放从年轻代存活的对象。一般来说老年代里存放的对象生命周期都比较长。
3.持久代
用于存放静态文件,如java类、方法等。持久代对来及回收没有显著影响。
通常意义上的JVM内存回收总是指堆内存回收。