0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

程序员眼里的内存(下)

jf_78858299 来源:码农的荒岛求生 作者:码农的荒岛求生 2023-02-24 14:12 次阅读

本节是操作系统系列教程的第三篇文章,属于操作系统第一章即基础篇,在真正开始操作系统相关章节前在这一部分回顾一些重要的主题,以下是目录,由于本文篇幅较多因此按上篇、中篇、下篇三次发布,目录中黑体为本篇内容,本文为该主题最后一篇。


什么是内存

C/C++内存模型

堆区与栈区的本质

JavaPython等内存模型

Java内存模型

Jave中的堆区与栈区是如何实现的

Python内存模型

指针与引用

**进程的内存模型

**

**幻想大师-操作系统

**

总结


指针与引用

在各种编程语言中我们应该经常听到两个词,那就是引用或者指针。这两个词都是和内存相关的,指针和引用的作用都是“如何找到存放在内存上的数据”。

C/C++中有“指针”这样一个概念,而其它语言比如Java、Python有的只是“引用”这样一个概念。这两者有什么区别呢?我们打个比方你就能理解了。

“引用”就好比一个人的外号一样,就好有个程序员叫令狐冲,但是令狐冲同学在A公司的英文名可能是“Tom”,在B公司中可能又叫“Jerry”,那么在A公司中你只需要喊一声“Tom”就能找到令狐冲同学。

而“指针”强调的是位置,比如令狐冲在A公司的工位是“10排第二个”,在B公司中的工位是“8排第六个”,下班后回的位置在“中关村”。

这个例子当中的令狐冲同学就好比程序语言中的对象,令狐冲的各种外号就好比对象的引用,令狐冲当前所在的位置就好比对象的指针。

虽然通过“引用”和“指针”都能找到令狐冲同学,但是寻找的方式是不一样的。

只有C/C++这样的编译型语言才会有“指针”这样一个概念,指的是当前的对象放在了内存中的哪个位置上了。在比如Java、Python等语言中只有“引用”这样一个概念。

在C/C++语言中,我们可以通过指针直接找到一个对象,因为你知道这个对象就在内存中指针所指向的位置,但在Java、Python等语言中,当你利用引用找到对象时基本上是冲着解释器喊一句“Hey,解释器,帮我找到令狐冲这个对象”,解释器通过记录查找到这个对象,注意解释器是知道对象在内存中的真正位置的,由于直接管理内存是一项非常繁琐容易出错的事情(C/C++程序员一定对此有深刻体会),因此解释器就接手了对内存直接管理, Java、Python等程序员是没有必要知道对象在内存中的真正位置的 ,没有指针也可以开心的写程序而且程序更加健壮,何乐不为呢,因此这些语言中是没有指针这样一个概念。

Sun的一篇论文中提到了为什么Java里没有指针。

Most studies agree that pointers are one of the primary features that enable programmers to inject bugs into their code. Given that structures are gone, and arrays and strings are objects, the need for pointers to these constructs goes away. Thus, Java has no pointer data types. ...

You no longer have dangling pointers and trashing of memory because of incorrect pointers, because there are no pointers in Java.

大意是Java设计者认为指针太有技巧性以至于很容易出错,因此Java中没有指针。其实不只是Java,流行的语言当中除了C/C++之外几乎都没有指针。

在这一节中,你只需要理解以下两点就可以啦。

  • 指针:直接在内存中找到变量所在位置。所以指针是实实在在的内存地址。
  • 引用:告诉解释器你想使用的变量,然后解释器再去内存中找到变量的位置。所以引用只是解释器的一个 承诺 ,只要这个变量存在,解释器就承诺能找到这个变量,程序员就可以使用这个变量,至于这个变量在内存中的什么地方是不需要程序员关心的。
进程的内存模型

我们已经在前面几个小节中研究了C/C++以及Java、Python程序的内存模型,接下来让我们回到操作系统。

我们已经知道了,不管什么语言,最后操作系统看到的都是C程序,C程序在内存运行起来就是进程。而在前面的小节当中我们已经知道进程在内存中的样子,但那里的描述其实是不完整的,也是不准确的。接下里我们就来看一下,操作系统中的进程在内存中到底是什么样子的,如下图所示(注意这幅图描述的是32位操作系统下进程在内存中是什么样子的),我们需要注意以下几点:

  1. 在上图中多出了一块内存,注意,这块内存就是操作系统在运行的时候所占用的内存。
  2. 每个进程独占一个连续的4G大小的内存,从内存地址0开始,一直到0xffffffff,其中最上方的1G留给了操作系统使用,下方的3G是留给进程自己使用的,其中程序员可以操作的区域就是图中的堆区和栈区。
  3. 你会发现代码段下方也有一点空隙没有使用,其实这是有特殊目的的,具体用途会在后面的章节中讲解。

现在你已经知道了进程在内存中的样子,你一定会有疑问吧,

为什么每个进程认为自己占用的是4G内存呢? 如果我的PC上只有2G内存,进程还是认为自己拥有4G内存吗

操作系统上不是可以同时运行很多进程吗,内存是有限的,假如只有2G, 每个进程都认为自己拥有4G内存,这不会有问题吗

我们首先来回答第一个问题:是的,每个进程都认为计算机上的真实内存就是4G,而且是进程自己独占的,即使真正的物理内存只有256MB。

第二个问题:很显然,不管你现在看这篇文章用的电脑,iPad安卓手机还是iPhone,这些计算设备中的进程都是这么认为的,你能看到这篇文章说明进程认为自己拥有4G内存是不会出现问题的。

在这里需要再次强调的是:

每个进程都认为真实的内存就是4G,其中1G被操作系统使用,剩余部分被进程使用,也就是可以被程序员使用。 注意这是不受真实物理内存限制的 ,也就是说,即使真实的物理只有256MB,进程同样认为在内存是4G,其中1G是操作系统的,剩余3G是进程自己独占的,程序员依然可以按照内存大小是3G来写程序。所以在大小256MB的真实物理内存上,程序员依然可以一次性申请超过256MB的内存而且可以申请成功,后续内存的使用也不受影响。

就像我第一次知道这种魔法时一样,你肯定也会惊呼这怎么可能呢? 我们怎么能在256MB大小的内存上申请超过256MB的内存呢 ?但事实就是如此,你可以在物理内存大小为256MB的内存上面申请超过256MB的内存,而且无论物理内存大小,每个进程都认为自己拥有4G内存,而且是独占内存。

这真的是太神奇了,这就是本课程的主角-操作系统带来的神奇魔法。

幻象大师——操作系统

这种魔法确实是真实的,这个魔法就来自我们的幻象大师- 操作系统 ,其实进程看到的内存是操作系统制造的幻觉。操作系统让每个进程都认为内存就只有两部分,一部分是操作系统的一部分是自己的,这种魔法就称之为虚拟内存。后面的章节中会重点介绍操作系统是如何实现这种魔法的。

在虚拟内存上程序员分配内存不受真实物理内存大小的限制

但这仅仅是进程自己这么认为,这是操作系统给进程制造的幻觉,所以被称之为虚拟内存。虚拟内存是操作系统中极为重要的概念,和进程一样,对虚拟内存的深刻理解也是编程高手的标志之一。我会在后续文章中来为大家透彻讲解操作系统是如何做到的。

总结

哈哈,这真是比较长的一节,希望你能坚持学到这里,没办法,内存真的是非常重要的, 要想学好操作系统,对内存的透彻理解是必不可少的

在这一节中我们认识到了其实内存仅仅就是一堆装0或1的小盒子组成,是没有什么神秘的。我们也了解了C/C++、Java、Python程序的内存模型,也知道了操作系统中的进程在内存中是什么样子的。同时操作系统中被被称为虚拟内存的神奇魔法也着实让人惊叹,想学习这么魔法请继续关注操作系统系列文章。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    2801

    浏览量

    73126
  • 编程语言
    +关注

    关注

    9

    文章

    1896

    浏览量

    33814
  • python
    +关注

    关注

    53

    文章

    4705

    浏览量

    83705
收藏 人收藏

    评论

    相关推荐

    成为优秀程序员的条件(

    (接“成为优秀程序员的条件(上))7 需求理解能力。程序员需要理解一个模块的需求,评估该模块在系统运营中所处的环境8 复用性,模块化思维能力。程序员在完成任何一个功能模块或函数的时候,要多想一些
    发表于 08-22 11:52

    【PDF】《疯狂的程序员

    `内容简介 · · · · · ·   本书描写了绝影等程序员的成长之路,分为大学、工作、创业三部分。作者笔下以绝影、BOSS liu、Bug Yang等为代表的程序员是大多程序员成长的真实写照
    发表于 03-08 14:06

    疯狂的程序员

    疯狂的程序员
    发表于 08-04 13:09

    程序员修养

    程序员修养
    发表于 08-19 22:36

    程序员的好习惯

    程序员的好习惯
    发表于 08-06 16:34

    与一群天才程序员一起工作是什么感觉?

    我是公司里一个特别普通的程序员,在我周围有很多在一小时内就能毫不费力地写出好几百行高效的代码的真正的天才程序员,而我要花更长时间来写,并且写出来的代码还需要进一步调整。我感觉在他们眼里我很没有存在感,在背后议论我做的不够好。该怎
    发表于 12-03 14:58

    程序员的快乐:那些小细节

    的重要因素。总得来说,快乐的程序员编码速度更快、Bug也更少。那么这些小细节都有哪些呢?下面就来介绍一。1、合适的硬件注意“合适”这个词。编程由正确的电脑开始。公司购买合适的电脑并不会倾家荡产。每家公司关于
    发表于 12-11 14:10

    程序员的幽默——献给所有程序员

    1. 某程序员对书法十分感兴趣,退休后决定在这方面有所建树。于是花重金购买了上等的文房四宝。一日,饭后突生雅兴,一番磨墨拟纸,并点上了上好的檀香,颇有王羲之风范,又具颜真卿气势,定神片刻,泼墨挥毫
    发表于 10-31 18:43

    程序员越老越优秀吗?

    Peter Knego 向我们展示了一些有趣的东西: 官方数据:程序员年纪越大越出色、越稀有。他使用StackOverflow的声誉值和其它几个指标来印证他的观点。他的总结是:随着年龄的增加,程序员
    发表于 10-25 10:04

    程序员的春联

    程序员写春联,秒杀全场!网友不愧是聪明绝顶的“程序猿”!
    发表于 04-08 11:39

    程序员为什么用Mac系统

    #Mac为什么会成为程序员的首选?程序员为什么都想要一台Mac?
    发表于 08-28 08:57

    #1024程序员节#话题讨论:不会填坑的程序员不是一个好程序员

    作为程序员的你是否经常遇到这样的情景:负责开发的项目遇到线上bug,心想这不是我的锅,先不管了,放着吧;代码写完后,隐隐感觉有问题,可程序跑得通,先用着吧;接手一个老系统,这什么破代码,算了,改吧改
    发表于 10-23 14:51

    作为一个程序员必须知道哪些内存的硬核知识点?

    作为一个程序员必须知道哪些内存的硬核知识点?
    发表于 10-13 08:26

    程序员眼里内存(上)

    本节是操作系统系列教程的第三篇文章,属于操作系统第一章即基础篇,在真正开始操作系统相关章节前在这一部分回顾一些重要的主题,算是温故知新吧,以下是目录,由于本文篇幅较多因此接下来会分三次发布,目录中黑体为本篇内容。
    的头像 发表于 02-24 14:07 250次阅读

    程序员眼里内存(中)

    *Java、Python等内存模型 ** **Java内存模型 ** **Jave中的堆区与栈区是如何实现的 ** **Python内存模型**
    的头像 发表于 02-24 14:09 400次阅读
    <b class='flag-5'>程序员</b><b class='flag-5'>眼里</b>的<b class='flag-5'>内存</b>(中)