内存分配
程序都会涉及内存分配,比起c来,Java对内存分配的涉及更远淡一些,不过编程总是要理解自己的内存。
曾经考虑怎样设计一个程序的内存,如果按照c的链表分配管理,就会产生碎片;如果按照Java的gc机制,就需要很多额外的处理。似乎都不是那么方便。最近在查相关知识的时候,看到内存池的概念。
Java的gc就是一种内存池技术。对c来说,写的程序可以灵活处理,如果是大块并且固定大小的动态分配,用链表的话就很容易整理;如果是小块或大小变换比较灵活,可以自己分配一大块内存作为内存池,并且自己做管理。这样就可以实现不同种类的需求。
而Java的gc是一个比较成熟的内存池。包括多线程的考虑以及最小化性能影响。
也就是gc是内存知识体系中内存池那部分,c可以用来表达这知识体系的更多部分。
写程序的时候,代码和临时数据都占用内存,内存管理是考虑数据内存的部分。每个代码都会处理一些数据,如果是很小的变量可以直接放到栈上,如果是通用的数据或者动态的数据就需要另找一个地方单独放置。
Java的gc或者c的malloc,都把这些数据内存放置到一个代码块无关的固定区域。当代码块引用到这些数据的时候都去这部分固定区域去访问或创建。在之前,汇编语言编辑简单程序的时候,每个代码块用到的数据都是和代码块相关连、和代码块放到一起。如果一个代码块被多个客户线程访问,会产生不定量的临时数据,这些没放到栈里的、动态的临时数据,或许也可以放到代码块的附近。也就是每个代码块实际上抽象上都有一个大约量的动态内存占用,占用量的大小取决于代码块的被访问量或业务形式。
现在的方式仍旧是集体分配,每个分配都是和代码块位置不相关。这样代码块在访问相应数据的时候需要跳过一定的距离,不是直接在自己周围就可以访问到。这个跳转的距离,显得随机不可计算。
缓存的量有限,并且分级。不可能所有都缓存到,会涉及到替换策略。如果相关的代码块和相关的数据放在相邻的位置,会提高访问效率。现在还并没有能代码块和相关数据放置到相近空间的机制。需要访问数据的,就要跳转到所有代码块通用的数据区域,不管程序多么大。
这就像工厂生产产品,用的材料放到一个统一的仓库中。好几个工厂都要跑去有些远的共用仓库,没有自己的仓库。
工厂足够大的时候应该有能力建立自己的仓库。
代码量足够大,每块代码块或者每个功能模块,应该可以建立临近自己的数据区域。
现在语言的机制可以满足放到固定区域,并且做不同形式的统一管理。不知道是否可以有新的语言机制,可以使得代码块和相关数据内存可以放到临近,内存上连续。以整理出对内存更清晰的应用和管理。