site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com hi, Here the code: static void * AllocateVirtualBuffer(OS_MemorySize pBufferLength) { kern_return_t error; vm_address_t originalAddress = NULL; vm_address_t realAddress = NULL; mach_port_t memoryEntry; vm_size_t memoryEntryLength; vm_address_t virtualAddress = NULL; OS_Int32 errorCount; // Success! return (void *)realAddress; #ifdef mkDebug // Here's a little test... *(char *)realAddress = '?'; if (*(char *)virtualAddress != '?') OS_Debug_Log("VirtualRingBuffer: Test 1: vm magic failed\n"); *(char *)(virtualAddress + 1) = '!'; if (*(char *)(realAddress + 1) != '!') OS_Debug_Log("VirtualRingBuffer: Test 2: vm magic failed\n"); #endif errorReturn: if (realAddress) vm_deallocate(mach_task_self(), realAddress, pBufferLength); if (virtualAddress) vm_deallocate(mach_task_self(), virtualAddress, pBufferLength); return NULL; } void FreeVirtualBuffer(void *fBuffer, UInt32 pBufferLength) { kern_return_t error; On Sep 19, 2005, at 2:12 AM, plumber wrote: Should I be worried? Is my application leaking memory? How can I trace where the leak is happening? take a look here /Developer/Applications/Performance Tools/ Best Regards _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... I figured out that it is "leaking" in some code I used for a long time, it is a code that allocates a buffer that is circular by using a sort of Virtual memory technique... I picked this code up from the internet and it seems that causes the leak... I'm guessing that the vm_deallocate is not releasing all the memory. The current leak doesn't seem to be traceable by mallocdebug because it isn't using any of those calls... I was using that tool before... / /----------------------------------------------------------------------- ----------------- // AllocateVirtualBuffer / /----------------------------------------------------------------------- ----------------- // We want to find where we can get 2 * fBufferLength bytes of contiguous address space. // So let's just allocate that space, remember its address, and deallocate it. // (This doesn't actually have to touch all of that memory so it's not terribly expensive.) error = vm_allocate(mach_task_self(), &originalAddress, 2 * pBufferLength, TRUE); if (error) { #ifdef mkDebug OS_Debug_Break("vm_allocate initial chunk", error); #endif return NULL; } error = vm_deallocate(mach_task_self(), originalAddress, 2 * pBufferLength); if (error) { #ifdef mkDebug OS_Debug_Break("vm_deallocate initial chunk", error); #endif return NULL; } // Then allocate a "real" block of memory at the same address, but with the normal pBufferLength. realAddress = originalAddress; error = vm_allocate(mach_task_self(), &realAddress, pBufferLength, FALSE); if (error) { #ifdef mkDebug OS_Debug_Break("vm_allocate real chunk", error); #endif return NULL; } if (realAddress != originalAddress) { #ifdef mkDebug OS_Debug_Log("allocateVirtualBuffer: vm_allocate 2nd time didn't return same address (%p vs %p)\n", originalAddress, realAddress); #endif goto errorReturn; } // Then make a memory entry for the area we just allocated. memoryEntryLength = pBufferLength; error = mach_make_memory_entry(mach_task_self(), &memoryEntryLength, realAddress, VM_PROT_READ | VM_PROT_WRITE, &memoryEntry, NULL); if (error) { #ifdef mkDebug OS_Debug_Break("mach_make_memory_entry", error); #endif goto errorReturn; } if (!memoryEntry) { #ifdef mkDebug OS_Debug_Log("mach_make_memory_entry: returned memoryEntry of NULL\n"); #endif goto errorReturn; } if (memoryEntryLength != pBufferLength) { #ifdef mkDebug OS_Debug_Log("mach_make_memory_entry: size changed (from %0x to %0x)\n", pBufferLength, memoryEntryLength); #endif goto errorReturn; } // And map the area immediately after the first block, with length pBufferLength, to that memory entry. virtualAddress = realAddress + pBufferLength; errorCount = 0; while (errorCount <10) { error = vm_map(mach_task_self(), &virtualAddress, pBufferLength, 0, FALSE, memoryEntry, 0, FALSE, VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_DEFAULT); if (error) { #ifdef mkDebug OS_Debug_Break("vm_map", error); #endif // TODO Retry from the beginning, instead of failing completely. There is a tiny (but > 0) probability that someone // will allocate this space out from under us. virtualAddress = NULL; goto errorReturn; } else { break; } errorCount++; } if (virtualAddress != realAddress + pBufferLength) { #ifdef mkDebug OS_Debug_Log("vm_map: didn't return correct address (%p vs %p)\n", realAddress + pBufferLength, virtualAddress); #endif goto errorReturn; } / /----------------------------------------------------------------------- ----------------- // FreeVirtualBuffer / /----------------------------------------------------------------------- ----------------- // We can conveniently deallocate both the vm_allocated memory and // the vm_mapped region at the same time. error = vm_deallocate(mach_task_self(), (vm_address_t)fBuffer, pBufferLength * 2); if (error) { #ifdef mkDebug OS_Debug_Break("vm_deallocate in dealloc", error); #endif } } This email sent to site_archiver@lists.apple.com
participants (1)
-
Marc Van Olmen