(深入理解JVM)Java内存区域与内存溢出的异常

本文深入解析Java内存模型,包括程序计数器、虚拟机栈、本地方法栈、Java堆、方法区、运行时常量池及直接内存。阐述了对象创建过程、内存布局以及访问定位,帮助理解Java内存管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java内存的区域

程序计数器(线程私有)

程序计数器是一块很小的内存空间,可以被视作为当前线程所执行的字节码的行号指示器。如果线程执行的是java的 方法,这个计数器记录的虚拟机执行指令码的行数。如果执行的是Native的方法则计数器为空。不会出现OutOfMemoryError的错误。

java虚拟机栈(线程私有)

在每个方法执行的时候会创建一个栈帧,栈帧是用来存储方法中的局部变量表,操作数栈,动态链接,方法入口的等的信息,每个方法的调用到执行结束队形的就是在虚拟机栈中的入栈和出栈。

这里值得注意的是栈和堆的区别:

 1. 首先是被线程拥有的方式:栈内存是被线程私有的,而堆内存是被线程所共享的。
 2. 效果是不同的:栈内存用来存储的是每个方法当中的一些相关的内容比如(局部变量表,操作数栈,动态链接,方法入口等等),而堆中存储的是对象的实例。

抛出的异常为Stack OverflowError
或者是OutOfMemoryError

本地方法栈

这是在Java中调用本地方法时候会使用的内存空间,这个栈也会抛出OutOfMemoryError

java堆(线程共有)

Java堆(Java Heap)是虚拟机所管理内存的最大的一块的空间,其中垃圾回收主要回收的堆中的内存。
其中主要存储的是对象的实例几乎所有的实例都存在于堆中。
Java堆是垃圾回收的主要的区域因此被称为"Gc堆"(Garbage Collected Heap),从内存回收的角度可以分为:新生代和老年代,更细一点的划分为:Eden空间,From Survivor ToSurvivor空间

抛出的异常为 OutOfMemoryError

方法区(线程共有)

方法区用于存储:虚拟机加载的类的信息,常量,静态变量,即使编译器编译后的代码的数据。
我对方法区的理解为:方法区是用来存储Class文件的内容,当我们执行一个JAVAC命令的时候,我们便已经把这个类加载到了我们的java虚拟机当中。

抛出的异常为 OutOfMemoryError

运行时常量池(线程共有并且是方法区的一部分)

Class文件中包含类的版本(即魔数),字段,方法,接口等描述信息以外还包含一项信息为常量池(编译时期生成的各种字面变量和符号引用)。
运行时常量池可以动态的向里面添加内容,运行期间可能将新的常量放入池当中去。

抛出的异常为 OutOfMemoryError

直接内存

这块内存并不是java运行时数据区,但是由于引入的NIO的原因这个部分内容与NIO的内容相关。
NIO(New Input/Output)是基于通道和缓冲区的一种IO类。它可以使用Native函数来直接分配堆外内存,然后通过分配在Java堆中的DirectByteBuffer来作为这块对象的引用来对这块内存进行管理,这样的优点在于避免了数据复制到堆当中然后进行操作的时间,提高了性能。

这块内存受限于本机内存,也会抛出OutOfMemoryError异常。

对象的创建过程

1 类加载过程

2 创建对象的方式

如果类已经加载完全了,那么便可以去创建这类的对象的实例。
创建对象的实例可以有两种方式:
1 指针碰撞的方式:这样的方式是把堆内存分为两部分:使用了的和未使用的内存。这两个内存之间存在一个指针,这个指针用来记录两个部分。
2 空闲列表方式:这个方式是用一个列表来保存堆内存中没有被使用的内存部分,然后创建对象的时候把实例放在空闲的内处。
上面分配存在一点点缺点在于:没有处理好好并发情况下的问题。并发的问题解决的方法也有两种方式:
1 乐观的方式即采用CAS规则来判断,符合规则的时候再去分配内容。
2 创建了了一个TLAB(ThreadLocalAllocationTable)线程相关的分配列表,这个列表的作用在每一个线程里面创建一个空间来用来存储空表的内容

值得注意的是:当内存分配好了以后,会对实例中的内容进行内容初始化零值。

3 虚拟机对对象进行必要的设置

比如 是哪个类的实例,如何找到类的元数据信息,对象的哈希码,对象的GC年龄分代的信息。

4 最后执行的方法

对实例对象进行赋值。

对象的内存的布局

1对象头

对象头包含两部分信息:
1 存储对象自身运行时候的数据
2 类型指针:即对象指向它的类元数据的指针目的是为了让虚拟机知道这个对象是哪个类的实例。

2 实例数据

实例真正存储的数据。

3 对齐填充

对象访问的定位

在一个栈中如果想要访问一个对象,需要找到对象的位置,有两种寻找对象的方法。
1 句柄访问 指向实例在堆中的地址,也指向对象类型数据的指针
2 直接指针访问直接指向在堆中的地址,并且含有一个指向类型数据的指针。

基于数据挖掘的音乐推荐系统设计实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了类`MPU6050`,该类包含了初始化传感器、读取数据等方法。例如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同样为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到类似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值