C++ Using the new operator efficiently

前端 未结 3 1186
时光取名叫无心
时光取名叫无心 2021-01-14 09:04

When instantiating a class with new. Instead of deleting the memory what kinds of benefits would we gain based on the reuse of the objects?

What is the process of n

相关标签:
3条回答
  • 2021-01-14 09:36
    • new allocates memory for the class on the heap, and calls the constructor.
    • context switches do not have to occur.
    • The c++-runtime allocates the memory on its freestore using whatever mechanism it deems fit.

    Usually the c++ runtime allocates large blocks of memory using OS memory management functions, and then subdivides those up using its own heap implementation. The microsoft c++ runtime mostly uses the Win32 heap functions which are implemented in usermode, and divide up OS memory allocated using the virtual memory apis. There are thus no context switches until and unless its current allocation of virtual memory is needed and it needs to go to the OS to allocate more.

    There is a theoretical problem when allocating memory that there is no upper bound on how long a heap traversal might take to find a free block. Practically tho, heap allocations are usually fast.

    With the exception of threaded applications. Because most c++ runtimes share a single heap between multiple threads, access to the heap needs to be serialized. This can severly degrade the performance of certain classes of applications that rely on multiple threads being able to new and delete many objects.

    0 讨论(0)
  • 2021-01-14 09:41

    If you new or delete an address it's marked as occupied or unassigned. The implementations do not talk all the time with the kernel. Bigger chucks of memory are reserved and divided in smaller chucks in user space within your application.

    Because new and delete are re-entrant (or thread-safe depending on the implementation) a context switch may occur but your implementation is thread-safe anyway while using the default new and delete.

    In C++ you are able to overwrite the new and delete operator, e.g. to place your memory management:

    #include <cstdlib> //declarations of malloc and free
    #include <new>
    #include <iostream>
    using namespace std;
    
    class C {
    public:
      C(); 
      void* operator new (size_t size); //implicitly declared as a static member function
      void operator delete (void *p); //implicitly declared as a static member function
    };
    
    void* C::operator new (size_t  size) throw (const char *){
      void * p = malloc(size);
      if (p == 0)  throw "allocation failure";  //instead of std::bad_alloc
      return p; 
    }
    
    void C::operator delete (void *p){  
      C* pc = static_cast<C*>(p); 
      free(p);  
    }
    
    int main() { 
       C *p = new C; // calls C::new
       delete p;  // calls C::delete
    }
    
    0 讨论(0)
  • 2021-01-14 09:42

    You've asked a few questions here...

    Instead of deleting the memory what kinds of benefits would we gain based on the reuse of the objects?

    That depends entirely on your application. Even supposing I knew what the application is, you've left another detail unspecified -- what is the strategy behind your re-use? But even knowing that, it's very hard to predict or answer generically. Try some things and measure them.

    As a rule of thumb I like to minimize the most gratuitous of allocations. This is mostly premature optimization, though. It'd only make a difference over thousands of calls.

    What is the process of new?

    Entirely implementation dependent. But the general strategy that allocators use is to have a free list, that is, a list of blocks which have been freed in the process. When the free list is empty or contains insufficient contiguous free space, it must ask the kernel for the memory, which it can only give out in blocks of a constant page size. (4096 on x86.) An allocator also has to decide when to chop up, pad, or coalesce blocks. Multi-threading can also put pressure on allocators because they must synchronize their free lists.

    Generally it's a pretty expensive operation. Maybe not so much relative to what else you're doing. But it ain't cheap.

    Does a context switch occur?
    Entirely possible. It's also possible that it won't. Your OS is free to do a context switch any time it gets an interrupt or a syscall, so uh... That can happen at a lot of times; I don't see any special relationship between this and your allocator.

    New memory is allocated, who is doing the allocation? OS ?
    It might come from a free list, in which case there is no system call involved, hence no help from the OS. But it might come from the OS if the free list can't satisfy the request. Also, even if it comes from the free list, your kernel might have paged out that data, so you could get a page fault on access and the kernel's allocator would kick in. So I guess it'd be a mixed bag. Of course, you can have a conforming implementation that does all kinds of crazy things.

    0 讨论(0)
提交回复
热议问题