内存管理介绍
Posted WangLanguager
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存管理介绍相关的知识,希望对你有一定的参考价值。
一、内存管理
内存管理是计算机系统中的重要部分,主要负责对内存资源进行有效分配和利用。在操作系统中,主要通过内存管理单元(MMU)实现内存管理。下面分别介绍内存的基础知识、内存地址空间、内存分配和内存回收等内容。
1.内存的基础知识内存是计算机中用于存储和读写数据的硬件设备,它可以存储程序代码、数据、运行时产生的临时数据和内核数据等。内存的大小和速度都会直接影响计算机的运行效率和性能。
2.内存地址空间在计算机中,每个进程都有自己的地址空间,也就是所谓的虚拟地址空间。虚拟地址空间是由逻辑地址组成的,逻辑地址是相对于进程地址空间起始地址的偏移量。当进程访问虚拟地址时,操作系统会将虚拟地址映射到物理地址上,从而实现对内存的访问。
3.内存分配内存分配是指将可用内存划分为若干块,供进程使用。常见的内存分配方式有如下几种:(1)连续内存分配:将可用内存划分为一段一段的连续空间,每个进程占用一段连续的内存空间。(2)非连续内存分配:采用虚拟内存技术,将进程的虚拟地址映射到物理地址上,从而实现对内存的访问。
4.内存回收内存回收是指在进程结束或者不再需要内存空间时,将已分配的内存空间释放,以便其他进程或系统资源使用。常见的内存回收方式有如下几种:(1)局部回收:在进程退出时,操作系统自动回收分配给进程的内存空间。(2)全局回收:由操作系统或管理员手动回收进程的内存空间。
需要注意的是,在多进程或多线程的环境下,内存管理需要考虑同步和互斥等问题,以保证数据的一致性和安全性。
二、以下是一个内存管理的详细示例,包括内存分配、读写和释放等操作。
该示例采用了连续内存分配的方式,并使用了C语言的指针来进行内存访问。
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 5
int main()
int *arr = (int *)malloc(MAX_SIZE * sizeof(int)); // 分配5个整数所需的空间
if (arr == NULL)
printf("Memory allocation failed.\\n");
return -1;
// 对动态分配的内存进行随机赋值
for (int i = 0; i < MAX_SIZE; ++i)
arr[i] = rand() % 100;
// 输出当前数组的值
printf("Array content:\\n");
for (int i = 0; i < MAX_SIZE; ++i)
printf("%d ", arr[i]);
printf("\\n");
// 修改数组中第3个元素的值
arr[2] = 50;
// 输出修改后的数组
printf("New array content:\\n");
for (int i = 0; i < MAX_SIZE; ++i)
printf("%d ", arr[i]);
printf("\\n");
// 释放动态分配的内存
free(arr);
return 0;
在该示例中,使用malloc函数动态分配了5个整型变量所需的空间,并将返回的指针赋值给变量arr。如果内存分配失败,则打印分配失败的信息并退出程序。
接着,对动态分配的内存进行随机赋值,并输出当前数组的值。然后,修改了数组中第3个元素的值,并再次输出修改后的数组。
最后,在结束时使用free函数释放已分配的内存空间。
需要注意的是,在使用动态内存分配和释放时,需要谨慎处理内存泄漏和指针悬挂等问题,以避免出现程序非正常退出、崩溃等情况。同时,在多线程编程时,还需要考虑线程安全和同步问题,以确保数据的一致性和正确性。
Android 内存管理介绍
极力推荐Android 开发大总结文章:欢迎收藏
程序员Android 力荐 ,Android 开发者需要的必备技能
Android Runtime(ART)
和Dalvik虚拟机
使用 分页 和 内存映射 来管理内存。 这意味着应用程序修改的任何内存(无论是通过分配新对象通过映射页面)都将保留在RAM
中,并且不能被分页。
应用程序释放内存的唯一方法是释放应用程序持有的对象引用,即使垃圾收集器回收(GC)
回收内存 。
比如:如果系统想要在其他地方使用该内存,则可以将任何未经修改的映射到mmap
中文件(例如代码)分页出RAM
。
本页面介绍了Android
如何管理应用程序进程和内存分配。 有关如何在应用程序中更高效地管理内存的更多信息,请参阅管理您的应用程序的内存。
本篇文章主要介绍 Android
开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:
1.Android 垃圾回收机制(GC)
2.共享内存
3.内存的申请与回收
4.内存限制
5.不同App切换时的内存管理
1.Android 垃圾回收机制(GC)
ART 或 Dalvik虚拟机的托管内存环境会跟踪每个内存分配情况。 一旦它确定一段内存不再被程序使用,它将它释放回堆(Heap)
中,并且不需要程序员的任何干预。 回收托管内存环境中未使用内存的机制称为垃圾回收(GC)
。
垃圾收集有两个目的:
1.在程序中查找将来不再使用的数据对象(Object)
2.回收这些对象所占用的内存资源。
Android 的内存是一个典型的堆内存(Heap)
,这意味着系统会根据被分配的对象的预期寿命和大小有不同的分配桶。
例如,最近分配的对象属于年轻一代。 当一个对象保持足够的活动时间时,它可以被提升到一个老一代,然后是一个永久的世代。
每个堆的生成都有自己占用内存的上限。任何时候一旦内存即将被填满,系统就会执行一个垃圾回收事件去试图释放内存。垃圾收集的持续时间取决于它正在回收的那个对象以及回收多少个正在活跃的对象。
尽管垃圾器回收的速度相当快,但它仍然可能会影响应用程序的性能。并且你一般不会控制垃圾器回收你代码事件的时间。
系统垃圾回收机制具有一定运行中的标准,这个标准主要用于确定何时执行垃圾收集。当条件满足时,系统停止执行进程并开始垃圾收集。
如果垃圾回收发生在密集的处理循环(如动画)或音乐播放期间,可能会增加处理时间。这种增长可能会推动您的应用程序执行代码超过推荐的16ms
阈值,以实现高效流畅的帧渲染。
此外,您的代码流可能会执行各种强制垃圾收集事件的工作,或使其持续时间超过正常。例如,如果在alpha
混合动画的每个帧期间在for循环
的最内部分配了多个对象,则可能会占用大量的内存堆,并使用大量对象。在这种情况下,垃圾收集器将执行多个垃圾收集事件,并可能降低应用程序的性能。
有关垃圾收集的更多一般信息,请参阅垃圾收集。
2.共享内存
为了适应不同的RAM需求,Android 尝试在不同进程之间共享内存,共享内存的方法如下:
- APP共享Framework框架代码以及资源
每个APP
的进程都是从Zygote
进程中分离出来的。
Zygote 进程:
Zygote
进程是在系统启动并加载Framwork
框架代码和资源(如Activity Theme)
时开始。 要启动一个新的应用程序进程,系统会从Zygote
进程fork
分离出来,然后在新进程中加载并运行应用程序的代码。 这种方法允许大部分分配给Framework
框架代码和资源的RAM
页面与所有应用程序进程之间共享。
- 大多数静态数据可以跨进程共享
大多数静态数据被映射到一个进程。这种技术允许数据在进程之间共享,并允许在需要时将其分页。 示例静态数据包括:Dalvik
代码(通过将其放置在用于直接映射的预链接.odex
文件中),应用程序资源(通过将资源表设计为可以被映射的结构以及通过对齐APK的zip条目
) 以及.so文件中
的本地代码等传统项目元素。
- Android使用显式分配的共享内存区域(使用ashmem或gralloc)共享同一个动态RAM。
例如,窗口表面使用应用程序和屏幕合成器之间的共享内存,游标缓冲区使用内容提供者和客户端之间的共享内存。
由于共享内存的广泛使用,确定您的应用使用多少内存需要谨慎。 在调查您的RAM
使用情况中讨论了正确确定应用程序内存使用情况的技巧。如需获取更多内容,请看RAM
使用情况分析详解。
3.APP内存的申请与回收
Dalvik 虚拟机
会限制每个应用程序进程的虚拟内存范围。它定义了逻辑堆的大小,并且可以根据需要增长,但只能达到系统为每个应用程序定义的限制。
堆的逻辑大小与堆使用的物理内存量不同。在检查应用程序的堆时,Android 会计算一个名为“比例集合大小** Proportion Set Size ”(PSS)** 的值,该值与其他进程共享的脏页面(Page)
和干净页面(Page)
,并且数量与多少应用程序共享该RAM
成正比。(PSS)
总数是系统认为是您的物理内存的足迹。有关PSS的更多信息,请参阅RAM使用情况指南
。
Dalvik
堆不压缩堆的逻辑大小,这意味着 Android
不会整理堆以关闭空间。当堆的末尾有未使用的空间时,Android
只能缩小逻辑堆的大小。然而,系统仍然可以减少堆使用的物理内存。在垃圾收集之后,Dalvik
遍历堆并找到未使用的页面,然后使用madvise
将这些页面返回给内核。
因此,成对的大块分配和释放应该会导致所有(或几乎全部)所使用的物理内存的回收。但是,从小分配中回收内存的效率可能会低得多,因为用于小分配的页面仍可能与尚未释放的其他内容共享。
4.APP内存限制
为了维护一个主要的多功能环境,Android
对每个应用程序的堆大小设定了一个硬限制。 确切的堆大小限制根据设备有多少RAM
可用而有所不同。 如果您的应用程序已达到堆容量并尝试分配更多内存,则可能会收到OutOfMemoryError
。
在某些情况下,您可能需要查询系统以确定在当前设备上有多少堆空间可用 。
例如,确定有多少数据可以安全地保留在缓存中。 你可以通过调用getMemoryClass()
来查询这个数字。 此方法返回一个整数,指示可用于应用程序堆的兆字节数。
5.不同App切换时的内存管理
当用户在应用程序之间进行切换时,Android
会保留不在前台的应用程序(即对用户不可见,或者在最近最少使用(LRU)
缓存中运行诸如音乐播放之类的前台服务)。 例如,当用户第一次启动应用程序时,会为其创建一个进程; 但是当用户离开应用程序时,该过程不会退出。 系统保持进程缓存。 如果用户稍后返回到应用程序,系统将重新使用该进程,从而使应用程序切换更快。
如果您的应用程序具有缓存的进程,并且保留了当前不需要的内存,那么您的应用程序(即使用户不使用它)也会影响系统的整体性能。 由于系统内存不足,它会以最近使用最少的进程开始,终止LRU
缓存中的进程。 系统也考虑到保存最多内存的进程,并可以终止它们以释放RAM
。
注意:当系统开始在
LRU缓存中
查杀进程时,它主要是自下而上的
。 系统也考虑哪些进程消耗更多的内存,从而为系统提供更多的内存增益。 在整个LRU列表中
消耗的内存越少,留在列表中的机会就越好,并能够快速恢复。
至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!
以上是关于内存管理介绍的主要内容,如果未能解决你的问题,请参考以下文章
Entrust - Laravel 用户权限系统解决方案 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 - Powered by PHPHub