【从浅到深的算法技巧】内存

这篇具有很好参考价值的文章主要介绍了【从浅到深的算法技巧】内存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

3.内存

一个程序对内存的使用也和物理世界直接相关:计算机中的电路很大一部分的作用就是帮助程序保存一些值并在稍后取出它们。在任意时刻需要保存的值越多,需要的电路也就越多。你可能知道计算机能够使用的内存上限(知道这一·点的人应该比知道运行时间限制的人要多)因为你很可能已经在内存上花了不少额外的支出。

计算机上的Java对内存的使用经过了精心的设计(程序的每个值在每次运行时所需的内存量都是一样的),但实现了Java的设备非常多,面内存的使用是和实现相关的。简单起见,我们用典型这个词暗示和机器相关的值。

Java最重要的特性之一就是它的内存分配系统。它的任务是把你从对内存的操作之中解脱出来。分析内存的使用比分析程序所需的运行时间要简单得多,主要原因是它所涉及的程序语句较少(只有声明语句)且在分析中我们会将复杂的对象简化为原始数据类型,而原始数据类型的内存使用是预先定义好的,而且非常容易理解:只需将变量的数量和它们的类型所对应的字节数分别相乘并汇总即可。例如,因为Java的int数据类型是-2147483648到2147483647之间的整数值的集合,典型的Java实现使用32位来表示int值。其他原始数据类型的内存使用也是基于类似的考虑:典型的Java实现使用8位表示字节,用2字节(16位)表示一个 char值,用4字节(32位)表示一个int值,用8字节(64位)表示一个double或者long值,用1字节表示一个boolean值(因为计算机访向内存的方式都是一次1字节)。根据可用内存的总最就能够计算出保存这些值的极限数量。例如,如果计算机有1 GB内存(10亿字节),那么同一时间最多能在内存中保存3200万个int值或是1600万个double值。

3.1 对象

要知道一个对象所使用的内存量,需要将所有实例变量使用的内存与对象本身的开销(一般是16字节)相加。这些开销包括一个指向对象的类的引用、垃圾收集信息以及同步信息。另外,一般内存的使用都会被填充为8字节( 64位计算机中的机器字)的倍数。例如, 一·个Integer对象会使用24字节(16字节的对象开销,4字节用于保存它的int值以及4个填充字节)。类似地,一个Date对象需要使用32字节: 16字节的对象开销,3个int实例变量各需4字节,以及4个填充字节。对象的引用一·般都是一个内存地址,因此会使用8字节。例如,一个Counter对象需要使用32字节:16字节的对象开销,8字节用于它的String型实例变量(一个引用),4字节用于int实例变量,以及4个填充字节。当我们说明一个引用所占的内存时,我们会单独说明它所指向的对象所占用的内存,因此这个内存使用总量并没有包含String值所使用的内存。

3.2链表

嵌套的非静态(内部)类.例如我们的Node类(请见1.3.3.1 节),还需要额外的8字节(用于一个指向外部类的引用)。因此,一个Node对象需要使用40字节(16字节的对象开销,指向Item和Node对象的引用各需8字节,另外还有8字节的额外开销)。因为Integer对象需要使用24字节,一个含有N个整数的基于链表的栈需要使用(32+64N) 字节,包括Stack对象的16字节的开销,引用类型实例变量8字节。int型实例变量4字节,4个填充字节,每个元素需要64字节,一个Node对象的40字节和一个Integer对象的24字节。

3.3 数组

Java 中数组被实现为对象,它们一般都会因为记录长度而需要额外的内存。一个原始数据类型的数组一般需要24字节的头信息( 16字节的对象开销,4字节用于保存长度以及4填充字节)再加上保存值所需的内存。例如,一个含有N个int值的数组需要使用(24+4N)字节(会被填充为8的倍数),一个含有N个double值的数组需要使用(24 +8N)字节。一个对象的数组就是一个对象的引用的数组,所以我们应该在对象所需的内存之外加上引用所需的内存。例如,一个含有N个Date对象(请见表1.2.12) 的数组需要使用24字节(数组开销)加上8N字节(所有引用)加上每个对象的32字节,总共(24+40N)字节。二维数组是一个数组的数组(每个数组都是一个对象)。例如,一个MXN的double类型的-维数组需要使用24字节(数组的数组的开销)加上8M字节(所有元素数组的引用)加上24M字节(所有元素数组的开销)加上8MN字节(M个长度为N的double类型的数组),总共(8MN+32M+24) ~ 8MN字节;当数组元素是对象时计算方法类似,结果相同,用来保存充满指向数组对象的引用的数组以及所有这些对象本身。

3.4 字符串对象

我们可以用相同的方式说明Java的String类型对象所需的内存,只是对于字符串来说别名是非常常见的。String 的标准实现含有4个实例变量:个指向字符数组的引用(8字节)和三个int值(各4字节)。所有字符所需的内存需要另记,因为string的char数组常常是在多个字符串之间共享的。因为String对象是不可变的,这种设计使String的实现在能够在多个对象都含有相同的value[]数组时节省内存。

3.5 字符串的值和子字符串

一个长度为N的String对象一般需要使用40字节(String对象本身)加上(24+2N)字节(字符数组),总共(64+2N)字节。但字符串处理经常会和子字符串打交道,所以Java对字符串的表示希望能够避免复制字符串中的字符。当你调用substring()方法时,就创建了一个新的String对象(40字节),但它仍然重用了相同的value[]数组,因此该字符串的子字符串只会使用40字节的内存。含有原始字符串的字符数组的别名存在于子字符串中,子字符串对象的偏移量和长度城标记了子字符串的位置。换句话说,一个子字符串所需的额外内存是一个常数,构造一个子字符串所需的时间也是常数,即使字符串和子字符串的长度极大也是这样。某些简陋的字符串表示方法在创建子字符串时需要复制其中的字符,这将需要线String对象 (Java库)性的时间和空间。确保子字符串的创建所需的空间(以及时间)和其长度无关是许多基础字符串处理算法的效率的关键所在。

这些基础机制能够有效帮助我们估计大量程序对内存的使用情况,但许多复杂的因素仍然会使这个任务变得更加困难。我们已经提到了别名可能产生的潜在影响。另外,当涉及函数调用时,内存的消耗就变成了一个复杂的动态过程,因为Java系统的内存分配机制扮演一个重要的角色,而这套机制又和Java的实现有关。例如,当你的程序调用-方法时,系统会从内存中的一个特定区域为方法分配所需要的内存(用于保存局部变量),这个区城叫做栈(Java系统的下压栈)。当方法返回时,它所占用的内存也被返回给了系统栈。因此,在递归程序中创建数组或是其他大型对象是很危险的,因为这意味着每一次递归调用都会使用大量的内存。当通过new创建对象时,系统会从堆内存的另一块特定区域为该对象分配所需的内存。而且,所有对象都会一直存在, 直到对它的引用消失为止。此时系统的垃圾回收进程会将它所占用的内存收回到堆中。这种动态过程使准确估计一个程序的内存使用变得极为困难。文章来源地址https://www.toymoban.com/news/detail-824549.html

到了这里,关于【从浅到深的算法技巧】内存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uniapp开发(由浅到深)

    1.1 脚手架构建 全局安装脚手架 npm install -g @vue/cli@4 ( 切记安装4.x.x的版本 ) 创建项目 vue create -p dcloudio/uni-preset-vue my-project 默认模板 执行命令参考 package.json 1.2 HBuilderX创建 uni-app项目步骤: 点工具栏里的文件 - 新建 - 项目 2.1 uView 安装依赖 ( 注意:项目名称不能有中文字符

    2024年02月13日
    浏览(30)
  • git使用(由浅到深)

    目录流程图 1.1 集中式版本控制 集中式版本控制系统有: CVS和SVN 它们的主要特点是单一的集中管理的服务器,保存所有文件的修订版本; 协同开发人员通过客户端连接到这台服务器,取出最新的文件或者提交更新 优缺点 相较于老式的本地管理来说,每个人都可以在一定程度

    2024年02月14日
    浏览(26)
  • mysql(由浅到深)

    数据库主要分为两类 : 关系型数据库 和 非关系型数据库 ; 关系型数据库: MySQL、Oracle、DB2、SQL Server、Postgre SQL 等; 关系型数据库通常我们会创建 很多个二维数据表 ; 数据表之间相互关联起来,形成 一对一、一对多、多对多 等关系 之后可以利用 SQL语句 在 多张表中查

    2024年02月16日
    浏览(30)
  • 微信小程序(由浅到深)

    1. 项目组成 2. 常见的配置文件解析 project.config.json :项目配置文件, 比如项目名称、appid等 ; 配置详情 sitemap.json :小程序搜索相关的;配置详情 app.json: 全局配置 page.json :页面配置; app.js 可共享全局属性值 3. app.json全局的五大配置 pages: 页面路径列表 用于指定小程序由

    2024年02月11日
    浏览(27)
  • 【面试题】 TypeScript 前端面试题 由浅到深

    1、前端面试题库 ( 面试必备 )             推荐:★★★★★ 地址:web前端面试题库 1.Boolean,Number,String 声明:类型 = 类型对应变量 类型收敛——字面量类型 2.undefined,null 在 TypeScript 中,null 与 undefined 类型都是有具体意义的类型。所以在默认情况下会被视作其他类型的

    2024年02月03日
    浏览(28)
  • 【万字解析】JS逆向由浅到深,3个案例由简到难,由练手到项目解析(代码都附详细注释)

    大家好,我是辣条哥! 今天给大家上点难度,不然总觉得辣条哥太菜了!我们今天聊聊JS逆向, 首先JS逆向是指对使用JavaScript编写的代码进行逆向工程,以获取代码的逻辑、算法或者进行修改。 下面举一个简单的例子来说明JS逆向的过程: 假设有一个网站,它使用了JavaScr

    2024年02月15日
    浏览(32)
  • 【算法】一文带你从浅至深入门dp动态规划

    本文要为大家带来的是dp动态规划,相信这是令很多同学头疼的一个东西,也是在大厂面试中很喜欢考的一个经典算法 🔰 本文总共会通过四道题来逐步从浅至深地带读者逐步认识dp动态规划 首先在讲解题目之前,我们要先来说说动态规划理论基础,让大家知道到底什么是【

    2024年02月07日
    浏览(32)
  • Unity内存优化技巧

            当涉及到Unity游戏的开发和优化时,内存管理是一个非常重要的方面。合理地管理和优化内存可以显著提高游戏性能并减少资源消耗。在本篇博客中,我们将探讨一些Unity内存优化的技术,并附带代码实现和注释,以帮助你更好地理解这些概念。         在游戏

    2024年02月07日
    浏览(38)
  • 虚拟机内存、处理器、内存、快照的修改方法(虚拟机VMware使用技巧 上 )

    1、基础设置 ①、内存 VMware有两项基础的设置 内存 和 处理器 。先说内存设置,主要是设置内存的大小。安装虚拟软件的主机内存最好不低于16G,最好32G。主机内存太小不适合运行虚拟机软件。 16G的内存可以主机和虚拟机对半分,主机留8G,虚拟机分8G。32G的内存可以按照主

    2024年02月09日
    浏览(37)
  • 提高代码效率的6个Python内存优化技巧

    当项目变得越来越大时,有效地管理计算资源是一个不可避免的需求。Python与C或c++等低级语言相比,似乎不够节省内存。 但是其实有许多方法可以显著优化Python程序的内存使用,这些方法可能在实际应用中并没有人注意,所以本文将重点介绍Python的内置机制,掌握它们将大

    2024年01月18日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包