java 内存分布,内存溢出

Java 内存区域分布

 Java虚拟机在执行Java程序过程中会将所管理的内存划分若干个区域,如下图为几个运行时数据区:


java 内存分布,内存溢出

  1. 程序计数器: 它是一小块内存区域,它可以当做当前线程执行字节码行号记录器。字节码解释器通过改变重写程序计数器的值来确定下一步执行那个字节码指令。

  2. 虚拟机栈:和程序计数器一样,Java虚拟机栈也是线程私有的。 和当前线程的生命周期一致。当执行一个Java方法时候会创建一个栈帧,用来寄存方法中的局部变量,当方法执行完毕,这个栈也随方法的结束而销毁。

  3. 本地方法栈:他和虚拟机栈是类似的,不同的是:虚拟机栈是 为执行Java方法(即字节码)服务,而 本地方法栈是 为虚拟机执行native 方法服务。和虚拟机栈一样的是 ,他们都会遭遇栈溢出和内存溢出异常。

  4. 堆:是虚拟机中最大一块内存区域,是所有线程共享的一片区域,她是虚拟机启动的时候就创建的。 他的唯一目的就是用于存放 实例对象 ,几乎所有创建的实例对象分配的内存都来与此地。堆是垃圾回收器主要管理的片区,目前的虚拟机都采用分代收集算法,将对象分类为 新生代和老年代,采用相应的算法来回收垃圾内存。

  5. 方法区:和堆一样,她属于线程共享区域。但是他存储的一般是Java类加载的class字节码信息,常量,静态变量等。

内存溢出

      除过程序计数器外,其他的内存区域都可能出现内存溢出的风险。我们来看一下。

  1. 堆内存溢出: 发成位置在堆区域,由于堆用来存储对象实例,不言位于堆内存溢出是由于不断创建对象,而对象实例未被及时的垃圾回收器回收造成的。一般我们在书写代码过程中主要 死循环中创建对象,同时可以优化 堆大小, xxs和xxm 来修改。