java内存区域详解

1 篇文章 0 订阅

一 .概述

在java中,我们去new一个对象时,不需要太过关注内存泄漏和溢出方面的问题,正是因为有了java虚拟机的控制,了解虚拟机是是如何使用内存是很有必要的。

二.运行时数据区域

线程私有:

  • 程序计数器
  • 虚拟机栈
  • 本地方法栈
    线程共享:
  • 方法区
  • 直接内存(非运行时数据区的一部分)
    在这里插入图片描述
    注:在jdk1.8方法区被作为元空间放在直接内存里
1.程序计数器

可以看作是执行当前线程的字节码行号指示器,每个线程有自己的程序计数器,字节码解释器通过改变计数器的值,来进行读取下一条操作指令,各个线程互不影响,所以说它是线程私有的,其生命周期随线程创建而创建,随着线程结束而死亡。

2.虚拟机栈

Java 虚拟机栈也是线程私有的,它的生命周期和线程相同,Java 虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表(boolean,byte,int,long,double,float,char,short和自定义对象的引用)、操作数栈动态链接方法出口信息

扩展:在函数/方法调用时,会出现对应的压栈动作,函数/方法调用结束后会有一个弹出栈帧动作,类似于数据结构中的进栈和出栈

2.本地方法栈

本地方法栈与虚拟机栈有点相似,区别在于:虚拟机栈是作用于执行java方法(字节码) 服务,本地方法栈是作用于执行 native方法(本地库方法) 的服务。

3.堆区

存储的全部是对象实例,每个对象都包含一个与之对应的class的信息(class信息存放在方法区)。 jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身,几乎所有的对象实例和数组都在堆中分配,也是垃圾回收的主要区域,垃圾回收机制这里不一一详解。

4.方法区

又叫静态区,跟堆一样,被所有的线程共享。它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。垃圾收集行为在此块区域很少出现。
在jdk1.8中方法区被分为元数据放在直接内存上,它受本机内存限制,并且永远不会得到 java.lang.OutOfMemoryError。元空间默认大小为ultimate,意味着内存不受限制,你也可以自定义调整其空间的大小。

4.1运行时的常量池

运行时常量池是方法区的一部分。Class 文件中除了有类的版本、字段、方法、接口等描述信息外,还有常量池信息(用于存放编译期生成的各种字面量和符号引用),但在jdk1.7以后版本,它从方法区中移除了,在堆中独立开辟了一片区域

三.关于内存异常的补充

在这里插入图片描述
StackOverFlowError: 若 Java 虚拟机栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候,就抛出 StackOverFlowError 异常。
OutOfMemoryError: 若 Java 虚拟机栈的内存大小允许动态扩展,且当线程请求栈时内存用完了,无法再动态扩展了,此时抛出 OutOfMemoryError 异常。Java 虚拟机栈也是线程私有的,每个线程都有各自的 Java 虚拟机栈,而且随着线程的创建而创建,随着线程的死亡而死亡。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值