您的位置:首页 > 其它

JVM 内存区域以及内存溢出和内存泄露

2017-12-09 19:58 330 查看
java 定义了若干种程序运行期间会使用到的运行时数据区,其中有的会随着虚拟机启动而创建,随着虚拟机退出而销毁,另外一些则是线程一一对应,这些与县城对应的数据库区域会随着线程开始而创建,线程结束而销毁

Java虚拟机规范将JVM所管理的内存分为以下几个运行时数据区:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区 运行时常量池。

PC 寄存器(程序计数器):

是当前线程所执行的字节码的行号指示器,字节码解释器工作时通过改变该计数器的值来选择下一条需要执行的字节码指令,分支、跳转、循环等基础功能都要依赖它来实现。 每一条java虚拟机线程都有自己的pc寄存器 各线程间的计数器互不影响,因此该区域是线程私有的

java 虚拟机栈 (也称为java栈): 线程私有

每一条java虚拟机线程都有自己私有的java虚拟机栈, 这个栈与线程同时创建用于存储栈帧,用于存储局部变量与一些过程结果的地方。

本地方法栈:

java虚拟机实现可能会使用到传统的栈,来支持native方法的执行,这个栈就称为本地方法栈

虚拟机栈与本地方法栈的区别在于:虚拟机栈为虚拟机执行Java方法服务器,本地方法栈为虚拟机使用到的native方法服务

java 堆“

堆是可供各条线程共享运行时的内存区域,也是供所有类实例和数组对象分配内存的区域,几乎所有的对象实例都在这里分配

java堆在虚拟机 启动的时候创建,他存储了被自动内存管理系统(GC 垃圾回收器) 所管理的各种对象,这些受管理的对象无序,也无法显式的销毁。 Java堆是垃圾回收器管理的主要区域,从内存回收的角度来看,由于现在收集器都基于分代收集算法,所以Java堆还可以分为新生代和老年代

方法区:

可供各条线程共享的运行时内存区域,他存储每一个类的结构信息,例如运行时常量池,字段和方法数据,构造函数,和普通方法的字节码内容,还包括一些在类,实例,接口初始化时使用到的特殊方法 。方法区在虚拟机启动的时候被创建

这里有一点要重点说明,在多线程情况下,给每个线程的栈分配的内存越大,反而越容易产生内存溢出异常。

运行时常量池:

是每个类或者接口的常量池的运行时表示形式。每一个运行时常量池都分配在 Java 虚拟机的方法区之中。在类和接口被加载到虚拟机后,对应的运行时常量池就被创建出来

内存泄露和内存溢出的区别:

内存泄露是指分配出去的内存没有被回收回来,由于失去了对该内存区域的控制,因而造成了资源的浪费。Java中一般不会产生内存泄露,因为有垃圾回收器自动回收垃圾,但这也不绝对,当我们new了对象,并保存了其引用,但是后面一直没用它,而垃圾回收器又不会去回收它,这边会造成内存泄露,

内存溢出是指程序所需要的内存超出了系统所能分配的内存(包括动态扩展)的上限。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: