JVM学习总结——Java内存区域

一、JVM的整体概述

在这里插入图片描述

二、Java运行时内存区域划分

JVM会在执行Java程序的过程中把它管理的内存划分为若干个不同的数据区域。这些数据区域各有各的用处,各有各的创建与销毁时间,有的区域随着JVM进程的启动而存在,有的区域则依赖用户线程的启动和结束而创建与销毁。一般来说,JVM所管理的内存将会包含以下几个运行时数据区域
在这里插入图片描述
其中栈分为虚拟机栈和本地方栈;两者是两个不同的概念但是是同一块区域

注意:加载到常量池的引用对应堆上的对象
程序执行起来时,就会在栈区开辟栈帧,销毁栈帧
运行时内存中的数据主要有两个来源:
(1)类文件加载进来的数据(放在方法区,常量池区为主)
(2)运行期间产生的数据(动态)(栈+堆为主)

1、PC程序计数器(线程私有)

程序计数器是一块比较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器

因为JVM的多线程是通过线程轮流切换并分配处理器时间的方式实现的,一个处理器都只会执行一条线程中的指令。因此为了切换线程后能恢复到正确的执行位置,每条线程都需要独立的程序计数器,各线程之间计数器互不影响,独立存储。所以PC计数器是线程私有的。

2、Java虚拟机栈(线程私有)

虚拟机栈描述的是Java方法执行的内存模型:每个方法执行的同时都会创建一个栈帧用于存储局部变量表。每一个方法从调用直至执行完成的过程,就对应一个栈帧在虚拟机中入栈和出栈的过程。

局部变量表: 存放了编译器可知的各种基本数据类型对象引用。局部变量表所需的内存空间在编译期间完成分配的,当进入方法时,这个方法需要在珍重分配多大的局部变量空间是完全确定的,在执行期间不会改变局部变量表大小。

此区域会有两种异常:
(1)如果线程请求的栈深度大于虚拟机所允许的深度(-Xss设置栈容量),将会抛出StackOverFlowError异常
(2)虚拟机在动态扩展时无法申请到足够的内存,会抛出OOM(OutOfMemoryError)异常

3、本地方法栈(线程私有)

本地方法栈与虚拟机栈的作用完全一样,他俩的区别无非是本地方法栈为虚拟机使用的Native方法服务,而虚拟机栈为JVM执行的Java方法服务。
在HotSpot虚拟机中,本地方法栈与虚拟机栈是同一块内存区域。

4、Java堆(线程共享)

Java堆(Java Heap)是JVM所管理的最大内存区域。在JVM启动时创建,此内存区域存放的都是对象实例。JVM规范中说到:“所有对象实例以及数组都要在堆上分配”。

Java对是垃圾回收器管理的主要区域,因此很多时候北城为“GC堆”
如果对重没有足够的内存完成实例分配并且对也无法拓展时,将会抛出OOM

5、方法区(线程共享)

方法区和Java对一样,是各个线程共享的内存区域。用于存储已被虚拟机加载的类信息,常量,静态变量。

JVM规范规定:当方法无法满足内存分配需求时,将会抛出OOM异常。

6、运行时常量池

常量池存放字面量与符号引用
字面量:final常量、基本数据类型的值
符号引用:类和结构体的完全限定名、字段的名称、方法的名称和描述符

JDK1.7后将字符串在堆中。

三、学习Java内存区域后增强对下面内容的理解

1、基本数据类型和引用数据类型怎么理解?
注意:Java中无论是基本数据类型还是引用数据类型都只有值传递

区别在于:
基本数据类型是==“直接”寻值==,直接找到的就是需要的值
引用数据类型是==“间接”寻值==,对象放在堆中。先找到对象,对象的值才是真正想要的值;改变形参,间接修改了对象的值,可以影响到实参。

2、引用和对象怎么理解
通过引用可以找到对象

引用本质上是一块小一点的内存地址,在常量池中,可以读取其中的内容,进而找到堆上的具体对象。

从应用者视角来看:对象就是真实事物的抽象(属性+方法)——万物皆对象

从JVM视角来看:对象是堆内存中的一块区域,
这块区域中有一些数据,被称为属性,
这块区域会和方法区中的某组方法(以类为单位)有绑定关系。

3、局部变量/属性(实例变量)/静态属性(静态变量) 怎么理解?
变量有很多的特征,可以从下面几个方面来看:

从类型来看: 数据类型和引用数据类型
从形态来看: 局部变量、属性、静态属性——变量在哪个区域是由形态决定的
作用域: 根据形态不同有不同的作用域 —— 空间上的范围
周期生命: 根据形态不同,有不同的生命周期 —— 时间上的范围

  局部变量:在方法、构造器或者块中使用,进入方法是被创建,方法退出时就会被销毁。
  属性:在类中声明,在方法、构造器或者块外;当堆中的对象被分配了一个空间时,属性的位置就被创建了,属性在堆中;也就是说当对象采用关键字“new”创建时属性就被创建了,当对象呗销毁时属性也就被销毁了。
  静态属性(静态变量):静态变量在堆区,存储在静态内存中;在类中用static关键字声明,在方法、构造器或者块之外。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值