深入理解Java虚拟机之内存区域与内存溢出
深入理解Java虚拟机之内存区域与内存溢出
YH_猿员猿 发表于2年前
深入理解Java虚拟机之内存区域与内存溢出
  • 发表于 2年前
  • 阅读 4
  • 收藏 0
  • 点赞 0
  • 评论 0

【腾讯云】新注册用户域名抢购1元起>>>   

当我们在c和c++编程的时候,我们对数据对象的操作与内存是紧密联系的,而在java编程中,我们并没有密切的关注内存是如何分配的,这些都交由java虚拟器进行管理,有时,我们运行一个程序的时候就可能发生内存泄露和溢出的问题。

关于java虚拟机的博客均参自与《深入理解Java虚拟机》这本书来做得一些笔记和体会。

java将内存划分为以下几个部分:
这里写图片描述

其中方法区和堆是有所有线程共享的
虚拟机栈,本地方法栈,程序计数器是线程隔离的

程序计数器

  1. 占用内存非常小,用于最基本的字节码的指令操作
  2. 每个线程的程序计数器相互独立
  3. 唯一一个在java虚拟机中没有规定任何OutMemoryError情况的区域。

Java虚拟机栈

  1. 线程私有,与线程同生共死。
  2. 作用为在Java方法的执行时创建栈帧,用于存储局部变量,操作数栈,动态链接,对应的栈的出栈和入栈,存储的为临时的信息。
  3. 两种异常:如果线程请求的栈的深度大于虚拟机所允许的,抛出StackOverflowError异常;如果虚拟机栈扩展超过Java虚拟机所允许的固定长度,则抛出OutMemoryError异常。

本地方法栈

  1. 与虚拟机栈相似,区别在于java虚拟机栈执行的是java方法服务,而本地方法栈是为虚拟机使用到的Native(本地方法支持)方法服务。
  2. 异常也有两个与虚拟器栈相同

Java堆

  1. Java堆是虚拟机中内存最大的一块,所有线程共享一块堆空间。
  2. 唯一目的:存放对象实例,自定义对象,数组….
  3. 是Java垃圾管理器管理(GC)的主要区域。
  4. 异常:当堆内存分配完毕,并无法扩展时,会抛出OutMemoryError异常。

方法区

  1. 各线程共享
  2. 主要用于存储已被虚拟机加载的类信息,常量,静态常量,即时编译器编译后的代码等数据。
  3. 垃圾回收较难,
  4. 与堆一样有OOM异常

运行时常量池

  1. 为方法区的一部分,就是存储常量的。
  2. 具有动态性。
  3. 异常与方法区一致。

直接内存

  1. 存放缓冲的,随着NIO(new Input/Output)的引入,引入的一种缓存机制
  2. 不属于java虚拟机
  3. 有内存超出异常

以上为个方法区域的总结。

Java对象的访问:

Object o = new Object();
创建对象会涉及到三个方法区。定义的obj变量会反射到Java本地变量表中,new Object()会在堆空间中分配一块存储Object对象所有属性和方法的结构化内存。对象的类型,父类,实现的接口等信息存储在方法区中。

访问方式:
1.句柄访问方式在堆中划分出句柄池,存储对象句柄地址。
2.直接指针访问

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 0
博文 12
码字总数 0
×
YH_猿员猿
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: