ION 内存管理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ION 内存管理相关的知识,希望对你有一定的参考价值。
参考技术A what is ION?ION 内存管理从android4.0开始被引入
ION模块是可扩展的(API都是统一的),支持各种形式的内存分配方式,可以表述不同的硬件资源和他们的一些限制
ION 支持连续与不连续内存的分配
ION 给Kernel and User space processes提供了相应的APIs
当前支持的memory type
ION_HEAP_TYPE_CARVEOUT - memory (PMEM style) for larger physically contiguous allocations
ION_HEAP_TYPE_SYSTEM_CONTIG - physically contiguous for small physical allocations
ION_HEAP_TYPE_SYSTEM - virtually contiguous but physically discontiguous memory
ION_HEAP_TYPE_IOMMU - memory region allocated through IOMMU API.
ION heap 的大小根据每个设备自身的内存情况而定,但是都要实现下面的回调:
struct ion_heap_ops
int (*allocate) (struct ion_heap *heap,
struct ion_buffer *buffer, unsigned long len,
unsigned long align, unsigned long flags);
void (*free) (struct ion_buffer *buffer);
int (*phys) (struct ion_heap *heap, struct ion_buffer *buffer,
ion_phys_addr_t *addr, size_t *len);
struct scatterlist *(*map_dma) (struct ion_heap *heap,
struct ion_buffer *buffer);
void (*unmap_dma) (struct ion_heap *heap,
struct ion_buffer *buffer);
void * (*map_kernel) (struct ion_heap *heap,
struct ion_buffer *buffer);
void (*unmap_kernel) (struct ion_heap *heap,
struct ion_buffer *buffer);
int (*map_user) (struct ion_heap *heap, struct ion_buffer *buffer,
struct vm_area_struct *vma);
;
方法phys(),返回的是的物理地址和buffer的长度,但必须是连续的物理buffer,如果没有连续的物理buffer,是不能提供改回调。
map_kernel() and unmap_kernel(),把物理内存映射到kernel virtual address space.
map_user(),映射物理内存到用户空间,为啥没有unmap_user()方法呢,因为映射到用户空间,是以FD(文件描述符)的形式映射的,当FD close了就自动unmap。
ION可以释放内存嘛?
答案是否定的。它主要的是提供给applications间共享内存。
ION和PMem可以共存嘛?
可以,但是不能共享buffers.
userspace是如何使用ION?
1:open ION device-------open("/dev/ion", O_RDONLY),返回一个FD(相当于ION client)
2: 客户端要填充如下数据结构,除了handle,也就是你要申请的data:
struct ion_allocation_data
size_t len;
size_t align;
unsigned int flags;
struct ion_handle *handle;
3: user space clients 用ioctl跟ION通信
int ioctl(int client_fd, ION_IOC_ALLOC, struct ion_allocation_data *allocation_data)
返回的FD的buffer。
4:FD可以通过Binder机制进行进程间的share
如何查看ION的使用量
for example:
>adb shell
#mount -t debugfs NONE /d
#cd /d/ion/
#ls
922
vmalloc
...
# cat vmalloc
cat vmalloc
client pid size
total bytes currently allocated: 0
# cat 922
cat 922
heap_name: size_in_bytes : handle refcount : buffer
client refcount: 1
ION 和DMABUF的比较:
Feature ION DMABUF
Memory Manager RoleION replaces PMEM as the manager of provisioned memory pools. The list of ION heaps can be extended per device.DMABUF is a buffer sharing framework, designed to integrate with the memory allocators in DMA mapping frameworks, like the work-in-progress DMA-contiguous allocator, also known as the Contiguous Memory Allocator (CMA). DMABUF exporters have the option to implement custom allocators.
User Space Access ControlION offers the /dev/ion interface for user-space programs to allocate and share buffers. Any user program with ION access can cripple the system by depleting the ION heaps. Android checks user and group IDs to block unauthorized access to ION heaps.DMABUF offers only kernel APIs. Access control is a function of the permissions on the devices using the DMABUF feature.
Global Client and Buffer DatabaseION contains a device driver associated with /dev/ion. The device structure contains a database that tracks the allocated ION buffers, handles and file descriptors, all grouped by user clients and kernel clients. ION validates all client calls according to the rules of the database. For example, there is a rule that a client cannot have two handles to the same buffer.The DMA debug facility implements a global hashtable,dma_entry_hash, to track DMA buffers, but only when the kernel was built with theCONFIG_DMA_API_DEBUG option.
Cross-architecture UsageION usage today is limited to architectures that run the Android kernel.DMABUF usage is cross-architecture. The DMA mapping redesign preparation patchset modified the DMA mapping code in 9 architectures besides the ARM architecture.
Buffer SynchronizationION considers buffer synchronization to be an orthogonal problem.DMABUF provides a pair of APIs for synchronization. The buffer-user callsdma_buf_map_attachment()whenever it wants to use the buffer for DMA . Once the DMA for the current buffer-user is over, it signals 'end-of-DMA' to the exporter via a call todma_buf_unmap_attachment().
Delayed Buffer AllocationION allocates the physical memory before the buffer is shared.DMABUF can defer the allocation until the first call todma_buf_map_attachment(). The exporter of DMA buffer has the opportunity to scan all client attachments, collate their buffer constraints, then choose the appropriate backing storage.
自动对象更改内存位置
【中文标题】自动对象更改内存位置【英文标题】:Automatic object changes memory location 【发布时间】:2016-06-05 01:47:26 【问题描述】:首先,让我们考虑一下我目前正在从事的一个项目的以下摘要。这是标题:
class GUI
public:
GUI& Initialize();
void DrawGUI(float width, float height);
private:
Model quad;
Shader sh;
Camera cam;
;
虽然这是 cpp 文件:
GUI& GUI::Initialize()
quad.Initialize().LoadModel("Resources/quad.obj");
sh = Shader().Initiliaze();
sh.models.push_back(&quad);
return *this;
void GUI::DrawGUI(float width, float height)
quad.SetScale(width, height, 0);
sh.RenderModels();
在直接解决问题之前,需要先解释一下。 Shader
对象 sh
将指向特定数量模型的指针存储在向量 vector<Model*> models
中。这些模型可以使用RenderModels
方法进行渲染。
在初始化过程中,GUI
通过quad
的地址&quad
将quad
添加到sh.models
。然后DrawGUI
方法可用于缩放quad
并将其绘制在屏幕上。
问题:
在我的主函数中使用DrawGUI
时,缩放没有效果!
这是由于我希望有人能为我解开的“神秘”行为。我已经知道问题的根源,但我无法理解其背后的原因。
虽然SetScale
函数修改了quad
的尺寸,但这不会影响渲染,因为(我在调试时已经验证过)&quad
和sh.models[0]
在调用DrawGUI
时具有不同的值。特别是,quad
在初始化和绘图调用之间的某个时间点更改了它的地址,而我没有任何干预。一个小改动解决了这个问题,然后缩放发生了:
void GUI::DrawGUI(float width, float height)
sh.models[0].SetScale(width, height, 0);
sh.RenderModels();
但这并不能帮助我理解为什么首先会出现问题。事情变得更不清楚了,虽然当GUI
被声明为使用自动存储时会出现问题,即GUI gui;
,但当我在堆上分配GUI
时它不会出现。事实上quad
不会更改地址,保持与sh.models[0]
相同,并且一切正常。
为什么两种分配方式之间的行为不同?我缺少关于自动分配的东西吗?为什么quad
地址变了?
【问题讨论】:
如果quad
的地址发生了莫名其妙的变化,则表明您有新的GUI
对象在您不期望的情况下被实例化。例如。如果你 push_back
和 GUI
到一个容器,它将创建它的副本。虽然您没有显示足够的代码来知道是否是这种情况,但是如果您在 GUI
构造函数中放置一个 cout
,您应该能够轻松判断是否发生了这种情况。
您是否尝试过使用已删除的复制构造函数?我的猜测是您将 GUI 作为副本传递给某个函数或其他东西。
@JonathanPotter 我刚刚尝试了cout
技巧。我只有一张印刷品……
您是否添加了显式复制构造函数?
删除拷贝构造函数和赋值运算符,重新编译工程。我敢打赌,你会看到编译错误。
【参考方案1】:
使用最新的 cmets,问题现在很清楚了。 OP的代码中存在以下行:
GUI gui = GUI().Initialize();
而Initialize
最重要的部分是:
GUI& GUI::Initialize()
// ...
return *this;
因此,GUI 对象的复制构造函数被调用。在没有任何用户提供的代码的情况下,使用默认的复制构造函数——并且由于 OP 还提到了指针,这些指针被复制为默认复制构造函数的一部分。但是没有人复制这些对象!事实上,没有人在新对象上调用Initialize
。
从给定的 sn-ps 解决方案尚不清楚,但有几件事是显而易见的:
不要使用Initialize
函数。使用构造函数,这就是它的用途。
仔细考虑复制您的对象。如有疑问,请删除复制构造函数和赋值运算符。
不要使用原始指针来管理对象,这就是智能指针的用途。在智能指针中,您的首选应该是unique_ptr
。
【讨论】:
好的,现在我明白了...我会尽量遵循您的指导,谢谢!以上是关于ION 内存管理的主要内容,如果未能解决你的问题,请参考以下文章
Linux 内核 内存管理memblock 分配器 ④ ( memblockmemblock_typememblock_region 结构体的关系 )