Java 内存结构

Java 内存结构

简介

    对于c  c++ 开发,内存管理他们拥有最高的权利,复杂一个对象生命的开始到终结。
    对于Java,程序员在虚拟机自动内存管理的机制帮助下,不再需要为每个new操作去配对free/delete代码,不容易出现内存溢出和泄漏问题,虚拟机管理内存是美好的。但如果出现内存溢出和泄漏,如果不知道虚拟机是如何使用内存的,那么排除错误是一件异常艰难的事。

运行时数据区域

java虚拟机在运行时将内存划分为若干个不同的数据区域,这些区域有不同的用途,以及创建和销毁的时间,根据java虚拟机规范的规定,java虚拟机所管理的内存分为以下几个区域。线程共享有: 方法区和堆 ,线程私有的有程序计数器、虚拟机栈(平时说的栈)和本地方法栈。如图:

程序计数器

这是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号器。字节码解释器工作时,就是通过改变它来选择要执行那条指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器完成。唯一一个没有OutOfMemoryError的区域。

虚拟机栈

线程在运行方法是都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息,每一个方法从调用到结束,表示一个栈帧的如栈出栈的过程。
平时我们说的栈内存一般指的就是虚拟机栈的局部变量表,里面存储这基本变量(boolean,byte,char,short,int,float,double,long)和对象的引用(reference)类型,对于longdouble占用两个局部变量空间,其余的数据类型只占用一个.
出现异常情况,1.请求的栈深度大于虚拟机允许的深度 2.无法申请到足够的内存,发生OutOfMemoryError异常

本地方法栈

与虚拟机栈相似,区别虚拟栈执行Java方法服务,本地方法栈使用到的是native方法服务

Java堆

这是Java内存中最大的一块,也是最重要的一块,是内存共享的.基本上所有的对象都是在这里创建的在这里分配内存,是Java垃圾处理器主要区域,也被称为gc堆(Garbage Collected  Heap),通过-Xmx-Xms控制大小。

方法区

线程共享,主要存储有加载的类信息,常量,静态变量和JIT编译后的代码等数据。
现在的永生代就是指方法区(很少GC),GC主要针对这个区域的常量池和类型的卸载,回收成绩相当令人不满意。在Sun公司的BUG列表中,有好几个严重的方法区内存泄漏的BUG。

常量池

个人感觉这块区域比较复杂.它分为两种形态
1.静态常量池,即存放class文件的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。
2.运行时常量池,即Jvm虚拟机在完成类加载操作后,将class文件中的常量池加载到内存中,并保存在方法区,我们平时说的常量池,就是指方法区中的运行时常量池

两则的关系,如图

对象访问定位

1.句柄访问对象

2.指针对象访问

猜你喜欢

转载自blog.csdn.net/ygh3334/article/details/81606328