JAVA新手入门09~一些内存知识普及

这一篇,我想分享下自己对于内存的一些基本知识的理解,当然,这篇文章也仅仅适用于新入门的Java开发人员,对于一些有经验的开发人员,可以不看,如果刷到了,请直接关闭页面就可以了。笔者写了很多年的Java代码,和写了很多年C语言的人相比,对于内存的理解,肯定要浅显很多。如果你是C语言开发者,本文对于你来说,简直就是脱了裤子放屁一样,觉的说的这不都是废话吗?哈哈一笑即可。

1、一些废话

一些废话还是要说,我们必须在一些概念上达成一致,首先这篇文章会特别的基础,其次这里说的内存,大部分情况下都是物理内存,不是虚拟内存(新手不知道虚拟内存的可以略过),这里讲的不少内容都是概念和理论性质的,少部分有实际的代码,主要是操作系统课程会讲到的内容。
如果你希望学到JVM内存管理的内容,那么你会失望。
如果你希望学习到程序开发的一些入门的内存知识,你会满意。

2、前菜:计算机存储设备

广义上讲的计算机的存储设备,一共有以下几种:

  • CPU的寄存器
  • 内存
  • 各种磁盘(例如机械硬盘、固态硬盘、U盘、光盘)
    这里我们主要讲内存,内存的容量单条都在4G 8G 16G了(2020年),寄存器和磁盘我们都不讲。

3、内存里的最小存储单元是字节

都知道计算机只能存储和计算2进制数据,都是0和1,毫无疑问,计算机内存中存储的都是0和1,那么这里有1个基本的概念,就是一个0或者一个1,叫做位,8位是1个字节。
那么这里我想说第一个知识点,内存里的最小存储单元是字节。
假设我们写了一行代码:

boolean a = false;

那么申请了几个字节呢?很显然用1个位就可以表示,但是实际是1个字节。

如果考虑到字节对齐,可能不仅仅是1个字节。如果你需要用1个位,实际上分配了1个字节的内存,这个就叫内存碎片,更精确的讲叫内部碎片。结论就是你不能申请少于1个字节的内存。

4、字节是有顺序的

继续刚才的话题,假设你写了如下一行代码:

long a = 0x12345678; // 转16进制之后是: 0x12345678 

这个数字,转换为2进制,就是:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7YID7oud-1609726062205)(…/img/image-20210102150223271.png)]
那么实际这个数字,在内存里是怎么存储的呢?由于Java不能查看实际的内存内容,这里我们借用C语言的GDB工具来实现,具体的过程就不写了,感兴趣的话,需要自己研究下。

(gdb) x/32xb 0x7ffeefbffb08
0x7ffeefbffb08:	0x00	0x00	0x00	0x00	0x00	0x00	0x00	0x00
0x7ffeefbffb10:	0x78	0x56	0x34	0x12	0x00	0x00	0x00	0x00
0x7ffeefbffb18:	0x25	0x10	0x01	0x00	0x00	0x00	0x00	0x00
0x7ffeefbffb20:	0x30	0xfb	0xbf	0xef	0xfe	0x7f	0x00	0x00
(gdb) x/32tb 0x7ffeefbffb08
0x7ffeefbffb08:	01111000	01010110	00110100	00010010	00000000	00000000	00000000	00000000
0x7ffeefbffb10:	01111000	01010110	00110100	00010010	00000000	00000000	00000000	00000000
0x7ffeefbffb18:	00100101	00010000	00000001	00000000	00000000	00000000	00000000	00000000
0x7ffeefbffb20:	00110000	11111011	10111111	11101111	11111110	01111111	00000000	00000000

我使用GDB查看了变量a的地址,然后查看了该地址的内存,可以看到低位的0x78,在内存的低地址,小端法。

1个int类型有4个字节,但是4个字节在内存中是有顺序的,如果低位的字节,在内存的低地址,这种存储方式就是小端,如果反过来,就是大端。

对于Java程序员来说,可以不用关心这个问题,基本上用不到这个知识的。

5、字节对齐

我们知道了内存中的最小单位是字节,那么很明显我们不能申请0.5字节或者1.5字节的内存长度,那么对于32位系统来说,还有1个要注意的地方是,大概率是4字节对齐的,什么意思呢?就是假设 一个类占3个字节,那么最终Java也会给你申请4个字节,这个就是字节对齐,为什么需要对齐呢?是因为32位系统的最大可以寻址2^32次方个字节,地址使用4字节的int表示的,所以访问的内存地址的物理地址,必须是4字节的整倍数,这样好寻址嘛,也很好理解。

我猜测,64系统大概率是8字节对齐的。
不过不用担心,Java虚拟机规范规定了int就是4字节,无论你是32位系统还是64位系统,所以还不需要关心这个事情,知道就可以了。所以有时候,我更倾向于把ArrayList的初始容量设置为16。

6、局部性原理

CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中。这个原理对于内存来说,更是如此。紧凑的内存数据更有利于计算机一次性把所有的数据都取出。

7、程序需要加载进内存才能执行

这简直就是脱了裤子放屁了,大家都知道。
所以有时候需要尽量把代码写的短一点,可能有一点点的好处,也完全可以忽略,毕竟不知道编译之后的目标代码到底怎么样。

8、虚拟内存

大部分情况下,程序员可以访问到的内存,都是虚拟内存,如果你的程序代码比你的内存还要大,直观的感受是这程序肯定不能运行,得益于虚拟内存,可以只加载一部分内存,然后按需加载。

全文完。

关注我的博客,获取更多Java编程知识: 双King的技术博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值