Java内存结构
Posted yghapsp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java内存结构相关的知识,希望对你有一定的参考价值。
Java 内存结构
简介
对于c c++ 开发,内存管理他们拥有最高的权利,复杂一个对象生命的开始到终结。
对于Java,程序员在虚拟机自动内存管理的机制帮助下,不再需要为每个new操作去配对free/delete代码,不容易出现内存溢出和泄漏问题,虚拟机管理内存是美好的。但如果出现内存溢出和泄漏,如果不知道虚拟机是如何使用内存的,那么排除错误是一件异常艰难的事。
运行时数据区域
java虚拟机在运行时将内存划分为若干个不同的数据区域,这些区域有不同的用途,以及创建和销毁的时间,根据java虚拟机规范的规定,java虚拟机所管理的内存分为以下几个区域。线程共享有: 方法区和堆 ,线程私有的有程序计数器、虚拟机栈(平时说的栈)和本地方法栈。如图:
程序计数器
这是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号器。字节码解释器工作时,就是通过改变它来选择要执行那条指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器完成。唯一一个没有OutOfMemoryError的区域。
虚拟机栈
线程在运行方法是都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息,每一个方法从调用到结束,表示一个栈帧的如栈出栈的过程。
平时我们说的栈内存一般指的就是虚拟机栈的局部变量表,里面存储这基本变量(boolean,byte,char,short,int,float,double,long)和对象的引用(reference)类型,对于long 和 double占用两个局部变量空间,其余的数据类型只占用一个.
出现异常情况,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.指针对象访问
以上是关于Java内存结构的主要内容,如果未能解决你的问题,请参考以下文章
java内存流:java.io.ByteArrayInputStreamjava.io.ByteArrayOutputStreamjava.io.CharArrayReaderjava.io(代码片段
14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段