zoukankan      html  css  js  c++  java
  • Using the C/C++ Garbage Collection Library, libgc

    Using the C/C++ Garbage Collection Library, libgc






    Article

    Using the C/C++ Garbage Collection Library, libgc








      


    By Mukesh Kapoor, Sun Microsystems - Sun ONE Studio Solaris Tools Development Engineering
     



    This article discusses some of the runtime errors related to memory
    management and how you can use the garbage collection library,
    libgc to fix these errors. In most cases, just linking with the library without
    making any changes to your
    code will fix the errors. You can get additional benefits by calling the functions
    available in the public Application Programming Interface (API) of
    the library. The library has a C API so you can use it with both C
    and C++ programs. libgc is included with the Sun C++ compiler product.


    Contents

     

    What Is Garbage Collection?
    What Does libgc Do?
    Common Memory Problems
    libgc API
    Modes of Operation
    Summary
    For More Information

     



    What Is Garbage Collection?

    Garbage collection deals with the automatic management of dynamic
    memory. You can dynamically allocate and deallocate memory by using the C++
    operators new and delete as well as by using the
    libc functions malloc() and free(). Managing
    dynamic memory is a complex and highly error prone task and is one of
    the most common causes of runtime errors. Such errors can cause intermittent
    program failures that are difficult to find and fix.

    A garbage collector automatically analyzes the program's data
    and decides whether memory is in use and when to return it to the
    system. When it identifies memory that is no longer in use, it
    frees that memory.

    The libgc library relieves you from the burden of explicit memory management.
    In addition, libgc automatically fixes memory related problems in
    third party libraries used in the application.

     



    What Does libgc Do?

    The libgc library is a conservative garbage collector that
    periodically scans a program's data and marks all heap objects that are in use.
    Once it has marked all heap objects that are reachable through pointers, it frees
    all the objects that have not been marked. It decides when to collect
    garbage by monitoring the amount of memory allocated since the last
    collection. When enough memory has been allocated, it performs the
    garbage collection.

    This way, programs that don't use a lot of dynamic memory won't
    spend much time in unnecessary garbage collection. The library has its own
    efficient memory allocator.

    Note-

    Do not use an outside allocator with libgc. The
    library provides the best performance with its own allocator. It will not
    automatically manage memory allocated by other allocators. If you use
    your own allocator, libgc will not search that memory for pointers to
    garbage collected memory.

     


     



    Common Memory Problems

    Using libgc fixes problems related to memory management in these
    broad categories:

    • Memory leaks
    • Premature frees
    • Memory fragmentation

    libgc does not, however, detect or fix problems due to memory overwrites.

     

    Memory Leaks

    This problem occurs if a program fails to free objects that are no
    longer in use. The following code leaks 100 bytes of memory every
    time the function test is called with the argument flag
    as false:

         void read_file(char*);
         void test(bool flag)
         {
             char* buf = new char[100];
             if (flag) {
         	     read_file(buf);
         	     delete [] buf;
             }
         }
    

    If a program continues to leak memory, its performance degrades.
    Its runtime memory footprint continues to increase and it
    spends more and more time in swapping and can eventually run
    out of memory.

     

    Premature Frees

    This is caused by freeing objects that are still in use, and
    can result in corrupted data and intermittent failures, including
    core dumps.
    Once memory is free, it becomes part of the system heap and can
    be reallocated later on for use in some other part of the program.
    If you try to access memory that has already been freed, you may end up
    accessing data in another, completely unrelated, part of the program.
    The memory corruption can show up at a time and place
    farther away from the actual point of error and can be very difficult
    to debug.

    The following code illustrates the problem:

         void eval(int*);
         void test2()
         {
             int* p1 = new int;
             int* p2 = p1;
             *p1 = 1;
             eval(p1);
             delete p1;
             *p2 = 2;   // the memory pointed to by p2 has already been deleted!
             eval(p2);
         }
    

    A variation of this is the case where the same memory
    pointer is deleted more than once:

         void test3()
         {
             int* p1 = new int;
             int* p2 = p1;
             delete p1;
             delete p2;  // deleting again!
         }
    

     

    Memory Fragmentation

    This can be caused by frequent allocation and deallocation of memory
    and can degrade an application's performance.
    Memory fragmentation occurs when a large chunk of memory is divided
    into much smaller, scattered pieces. These smaller discontiguous chunks
    of memory may not be of much use to the program and may never be
    allocated again. This can result in the program consuming more memory
    than it actually allocates.

     

    Memory Overwrites

    This problem occurs when too little memory is allocated
    for an object. Consequences can include memory corruption and intermittent
    failures. The program may work correctly some times and fail
    erratically at other times. Here is sample code that shows this problem:

         void test4()
         {
             char* x = new char[10];
             x[10] = '\0';  // memory overwrite!
         }
    

    libgc does not detect or fix this type of memory problem. You can
    use the Run Time Checking (RTC) feature in the debugger to find such
    errors.

     



    libgc API

    The libgc library has its own implementation of the C memory management
    functions malloc(), calloc(), realloc() and
    free().
    The library also provides the following three functions that can be
    called from a user program. You will need to include the header
    <gct.h> if you use any of these functions in your program.
    You can use any of the functions listed below in the library's development mode.
    See the following section for an explanation of libgc modes.
     

    void gcFixPrematureFrees(void)

    Fix premature frees. After this function is called, calls to
    free() will not do anything. The pointer passed as argument
    to free() will not be freed. The pointer will safely be
    freed later on when it is no longer in use.

    Note-

    Fixing premature frees may increase memory usage in
    some programs because the library defers the release of memory
    until it verifies that the memory is not being used. This is not
    an issue for most programs but may be important for some programs
    with strict memory constraints.

     


     

    void gcStopFixingPrematureFrees(void)

    Stop fixing premature frees. This reverses the effect of calling
    gcFixPrematureFrees.

     

    void gcInitialize(void)

    This function lets you configure your own settings and it works
    slightly differently than the other public API described above. The
    difference is that the libgc library calls gcInitialize
    at startup time so you should not call gcInitialize directly
    in your program. You can define your own function named
    gcInitialize in your program as shown in the following example:

         #include <gct.h>
         . . .
         void gcInitialize(void)
         {
              gcFixPrematureFrees();
         }
    

     



    Modes of Operation

    The library has two different modes of operation.
    In each mode, you can use the libgc library by specifying the
    option CC -library=gc or by specifying -lgc at link time.
    The -library=gc option is only available with the C++ compiler.
     

    Deployment Mode

    You can use this mode when you do not wish to modify your existing code
    or if you don't have access to the source code and can't modify it.
    To use libgc in deployment mode, link your application with
    the library and it automatically fixes memory leaks and memory
    fragmentation. It also speeds up memory allocation because
    it uses its own efficient malloc() function.

     

    Development Mode

    Development mode provides all the benefits of the deployment mode. In
    addition, you can write programs without ever calling
    delete or free(). The library takes care of freeing
    memory that is not in use. This feature provides one of the
    benefits of the Java programming language to C and C++ language
    programmers. If you are using delete or free() in
    your program, you can also fix premature frees in specific regions of
    your code by calling the functions gcFixPrematureFrees() and
    gcStopFixingPrematureFrees().

     



    Summary

    Using libgc automatically provides the following benefits
    in the user application:

    • Protects your program against memory leaks.
      Even if the programs use leaky third-party libraries, linking with
      libgc automatically fixes the leaks.
    • Allows you to write programs without calling delete or
      free(). This is a benefit of the Java programming
      environment which you can exploit for C and C++ programs.
    • Allows you to fix premature frees in your code.
    • Provides a fast non-fragmenting memory allocator. Programs linked
      with libgc run faster, use less space, and never fragment
      memory.

     



    For More Information

     

    Richard Jones and Rafael D Lins, Garbage collection,
    Algorithms for Automatic Dynamic Memory Management, Wiley, 1996
    Bjarne Stroustrup, Letter to the ANSI/ISO C++ committee, May 27, 1996.

     




    About the Author

    Mukesh Kapoor
    is a staff engineer in the C++ compiler group. He has
    an MS (Automation), BS (Electronics and Communication) from the Indian
    Institute of Science and BS (Physics) from Delhi University, India.
    Before joining Sun, Mukesh held various software development roles
    at Peritus Inc, Plexus computers, Elxsi and Unisoft Corp.

     








    Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.

  • 相关阅读:
    在QT函数中返回一个数组/把一个数组传参给函数
    QT储存内容到指定的文件内
    QT对linux下/sys/class/gpio中的gpio的控制
    QT 线程的暂停和继续
    QT的close和系统的close冲突
    画动态曲线另一种方式方式
    QT关于iCCP警告去除
    ps两张图片合在一起
    ps 做动态图
    解决MFC中因控件类多次Attch造成的销毁窗口过程中CWnd* pWnd = CWnd::FromHandlePermanent(hWnd); ASSERT(pWnd != NULL); 断言失败的问题
  • 原文地址:https://www.cnblogs.com/lexus/p/2591127.html
Copyright © 2011-2022 走看看