Java内存分配浅析1

工业互联网工控安全与工业质检AI大模型建设方案.pptx 立即下载

本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java。这类文章网上有很多,但大多比较零碎。本文从认知过程角度出发,将带给读者一个系统的介绍。

进入正题前首先要知道的是Java程序运行在JVM(Java  Virtual Machine,Java虚拟机)上,可以把JVM理解成Java程序和操作系统之间的桥梁,JVM实现了Java的平台无关性,由此可见JVM的重要性。所以在学习Java内存分配原理的时候一定要牢记这一切都是在JVM中进行的,JVM是内存分配原理的基础与前提。

简单通俗的讲,一个完整的Java程序运行过程会涉及以下内存区域:

l  寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制。

l  栈:保存局部变量的值,包括:1.用来保存基本数据类型的值;2.保存类的实例,即堆区对象的引用(指针)。也可以用来保存加载方法时的帧。

l  堆:用来存放动态产生的数据,比如new出来的对象。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。

l  常量池:JVM为每个已加载的类型维护一个常量池,常量池就是这个类型用到的常量的一个有序集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的符号引用(1)。池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用。常量池存在于堆中。

l  代码段:用来存放从硬盘上读取的源程序代码。

l  数据段:用来存放static定义的静态成员。

下面是内存表示图:

Java内存分配,IAVA

上图中大致描述了Java内存分配,接下来通过实例详细讲解Java程序是如何在内存中运行的(注:以下图片引用自尚学堂马士兵老师的J2SE课件,图右侧是程序代码,左侧是内存分配示意图,我会一一加上注释)。

预备知识:

1.一个Java文件,只要有main入口方法,我们就认为这是一个Java程序,可以单独编译运行。

2.无论是普通类型的变量还是引用类型的变量(俗称实例),都可以作为局部变量,www.linuxidc.com 他们都可以出现在栈中。只不过普通类型的变量在栈中直接保存它所对应的值,而引用类型的变量保存的是一个指向堆区的指针,通过这个指针,就可以找到这个实例在堆区对应的对象。因此,普通类型变量只在栈区占用一块内存,而引用类型变量要在栈区和堆区各占一块内存。

示例:

Java内存分配,IAVA

1.JVM自动寻找main方法,执行第一句代码,创建一个Test类的实例,在栈中分配一块内存,存放一个指向堆区对象的指针110925。

2.创建一个int型的变量date,由于是基本类型,直接在栈中存放date对应的值9。

3.创建两个BirthDate类的实例d1、d2,在栈中分别存放了对应的指针指向各自的对象。他们在实例化时调用了有参数的构造方法,因此对象中有自定义初始值。

Java内存分配,IAVA

调用test对象的change1方法,并且以date为参数。JVM读到这段代码时,检测到i是局部变量,因此会把i放在栈中,并且把date的值赋给i。

Java内存分配,IAVA

把1234赋给i。很简单的一步。

Java内存分配,IAVA

change1方法执行完毕,立即释放局部变量i所占用的栈空间。

Java内存分配,IAVA

调用test对象的change2方法,以实例d1为参数。JVM检测到change2方法中的b参数为局部变量,立即加入到栈中,由于是引用类型的变量,所以b中保存的是d1中的指针,此时b和d1指向同一个堆中的对象。在b和d1之间传递是指针。

Java内存分配,IAVA

change2方法中又实例化了一个BirthDate对象,并且赋给b。在内部执行过程是:在堆区new了一个对象,并且把该对象的指针保存在栈中的b对应空间,此时实例b不再指向实例d1所指向的对象,但是实例d1所指向的对象并无变化,这样无法对d1造成任何影响。

Java内存分配,IAVA

change2方法执行完毕,立即释放局部引用变量b所占的栈空间,注意只是释放了栈空间,堆空间要等待自动回收。

Java内存分配,IAVA

调用test实例的change3方法,以实例d2为参数。同理,JVM会在栈中为局部引用变量b分配空间,并且把d2中的指针存放在b中,此时d2和b指向同一个对象。再调用实例b的setDay方法,其实就是调用d2指向的对象的setDay方法。

Java内存分配,IAVA

调用实例b的setDay方法会影响d2,因为二者指向的是同一个对象。

Java内存分配,IAVA

change3方法执行完毕,立即释放局部引用变量b。

以上就是Java程序运行时内存分配的大致情况。其实也没什么,掌握了思想就很简单了。无非就是两种类型的变量:基本类型和引用类型。二者作为局部变量,都放在栈中,基本类型直接在栈中保存值,引用类型只保存一个指向堆区的指针,真正的对象在堆里。作为参数时基本类型就直接传值,引用类型传指针。

小结:

1.分清什么是实例什么是对象。Class a= new Class();此时a叫实例,而不能说a是对象。实例在栈中,对象在堆中,操作实例实际上是通过实例的指针间接操作对象。多个实例可以指向同一个对象。

2.栈中的数据和堆中的数据销毁并不是同步的。方法一旦结束,栈中的局部变量立即销毁,但是堆中对象不一定销毁。因为可能有其他变量也指向了这个对象,直到栈中没有变量指向堆中的对象时,它才销毁,而且还不是马上销毁,要等垃圾回收扫描时才可以被销毁。

3.以上的栈、堆、代码段、数据段等等都是相对于应用程序而言的。每一个应用程序都对应唯一的一个JVM实例,每一个JVM实例都有自己的内存区域,互不影响。并且这些内存区域是所有线程共享的。这里提到的栈和堆都是整体上的概念,这些堆栈还可以细分。

4.类的成员变量在不同对象中各不相同,都有自己的存储空间(成员变量在堆中的对象中)。而类的方法却是该类的所有对象共享的,只有一套,对象使用方法的时候方法才被压入栈,方法不使用则不占用内存。


C# WinForm项目目录结构详解:从入门到精通(附常见问题解决方案) 本文详细解析了C# WinForm项目目录结构,从解决方案与项目基础结构到核心文件功能,再到关键目录解析,帮助开发者快速掌握WinForm项目组织方式。文章还提供了常见问题解决方案,如引用丢失、配置文件不生效等,是WinForm开发从入门到精通的实用指南。 阅读详情

相关推荐

香橙派rk3588的rknn多线程推理RTSP流服务性能优化与资源分配策略

本文深入探讨了香橙派RK3588平台上的RKNN多线程推理在RTSP流服务中的性能优化与资源分配策略。通过分析硬件架构、设计多线程推理流水线、实现NPU核心负载均衡及优化RGA内存管理,显著提升了RTSP视频流的处理帧率和降低了延迟,为边缘计算视频分析应用提供了实用的优化方案。

7up55的博客 653

Java内存分配全面浅析

本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java。这类文章网上有很多,但大多比较零碎。本文从认知过程角度出发,将带给读者一个系统的介绍。          进入正题前首先要知道的是Java程序运行在JVM(Java  Virtual Machine,Java虚拟机)上,可以把JVM理解成Java程序和操作系统之间的桥梁,JVM实现了Java的平台无关性,由此可见JVM

杨元的博客 3万+

Unity 多线程编程笔记 _Task详解

士大夫

weixin_43405845的博客 4384

Java 内存分配全面浅析

本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java。这类文章网上有很多,但大多比较零碎。本文从认知过程角度出发,将带给读者一个系统的介绍。 进入正题前首先要知道的是Java程序运行在JVM(Java Virtual Machine,Java虚拟机)上,可以把JVM理解成Java程序和操作系统之间的桥梁,JVM实现了Java的平台无关性,由此可见JVM的重要性。所以在学习

观千剑而后识器,操千曲而后晓声。 11万+

条码打印工具-Bartender的使用

文章目录1、安装Bartender1.解压安装包,可获得bartender2021版本和破解文本2. 双击“BarTender_2021_R1_Full_x64.exe”文件运行,勾选协议及软件安装设置3. 选择安装选项,自行选择勾选,点击Browser可更换软件安装路径4. 耐心等待软件安装完成,直接点击完成退出5. 此时会弹出提示需要激活许可证,先点击取消6. 接着将Crack夹中的“BarTend.exe”破解文件复制到软件安装目录中替换7. 再双击“serial.reg”导入注册,点击确定即可8.

暮紫的笔记本 1万+

基于Ardupilot/PX4固件,APM/PIXhawk硬件的VTOL垂直起降固定翼软硬件参数调试(第一篇)安装调试

基于Ardupilot/PX4固件,APM/PIXhawk硬件的VTOL垂直起降固定翼调试 本文内容大部分来自Kris,我们的K大,在VTOL领域的大牛,在此,非常感谢K大。能引用K大的成果也是自己的荣幸,不便之处还请K大多多包涵,在此引用只是为方便自己日常学习,部分参数表里根据自身情况,增加了相应参数。 1.安装及下载Ardupilot官方固件: VTOL固件的来源可分为Ardupilot官方固...

u011322358的博客 3万+

java 内存分配全面浅析

本文转载于:http://blog.youkuaiyun.com/shimiso,写的很详细,大神,膜拜吧!!!哈哈 本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java。这类文章网上有很多,但大多比较零碎。本文从认知过程角度出发,将带给读者一个系统的介绍。 进入正题前首先要知道的是Java程序运行在JVM(Java Virtual Machine,Java虚拟机)上,

L未若的博客 543

Arduino智能小灯DIY:人体感应+光线感应+蓝牙控制全攻略(附完整代码)

本文提供了一份完整的Arduino智能小灯DIY制作指南。项目融合了人体感应、光线感应与蓝牙控制三大功能,通过详细的硬件清单、电路连接图、核心逻辑讲解及附带的完整代码,手把手教你打造一个能自动感知环境与人、并支持手机远程控制的智能照明装置,是入门智能家居和物联网开发的绝佳实践。

java5的博客 1093

(转)Java 内存分配全面浅析

转载于https://blog.youkuaiyun.com/shimiso/article/details/8595564 本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java。这类文章网上有很多,但大多比较零碎。本文从认知过程角度出发,将带给读者一个系统的介绍。 进入正题前首先要知道的是Java程序运行在JVM(Java Virtual Machine,Java虚拟机)上,可以...

im_cheer的博客 253

IC618新手避坑指南:从零在Linux上配置Cadence Virtuoso环境(含cds.lib文件详解)

本文详细介绍了在Linux系统上配置Cadence Virtuoso IC618环境的完整指南,特别针对新手常见问题提供解决方案。重点解析了cds.lib文件的关键配置,包括库路径定义和工艺库管理,并分享了高效工作流设置和典型问题排查技巧,帮助工程师快速搭建稳定的EDA设计环境。

weixin_26805597的博客 551

IDEA 2023.2最新破解安装教程(含详细配置步骤及常见问题解决)

本文详细介绍了IDEA 2023.2的安装流程及高效开发环境搭建指南,涵盖基础配置、项目结构优化、核心功能使用、插件推荐、性能优化等全方位内容,帮助开发者快速掌握这一强大的Java开发工具。

x2y3z4a5b的博客 1749
上一篇: JSP传参
下一篇: Java内存分配浅析2
架构师的清醒
博客等级 码龄14年 291粉丝 397原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值