官术网_书友最值得收藏!

Collecting garbage: why and how

Here are some reasons for using smart pointers and the garbage collection system in programming:

  • Fewer bugs: Using smart pointers means the automatic initialization and cleanup of pointers. No dangling pointers will be created because they are always reference-counted.
  • Efficient management: Objects will be reclaimed as soon as they are no longer referenced, which gives more available memory to applications with limited resources.
  • Easy to debug: We can easily obtain the referenced counting number and other information on objects, and then apply other optimizations and experiments.

For instance, a scene graph tree is composed by a root node and multiple levels of child nodes. Assuming that all children are managed with osg::ref_ptr<>, user applications may only keep the pointer to the root node. As is illustrated by the following image, the operation of deleting the root node pointer will cause a cascading effect that will destroy the whole node hierarchy:

Collecting garbage: why and how

Each node in the example scene graph is managed by its parent, and will automatically be unreferenced during the deletion of the parent node. This node, if no longer referenced by any other nodes, will be destroyed immediately, and all of its children will be freed up. The entire scene graph will finally be cleaned without worries after the last group node or leaf node is deleted.

The process is really convenient and efficient, isn't it? Please make sure the OSG smart pointer can work for you, and use a class derived from osg::Referenced as the osg::ref_ptr<> template argument, and correctly assign newly-allocated objects to smart pointers.

A smart pointer can be used either as a local variable, a global variable, or a class member variable, and will automatically decrease the referenced counting number when reassigned to another object or moved out of the smart pointer's declaration scope.

It is strongly recommended that user applications always use smart pointers to manage their scenes, but there are still some issues that need special attention:

  • osg::Referenced and its derivatives should be created from the heap only. They cannot be used as local variables because class destructors are declared protected internally for safety. For example:
    osg::ref_ptr<osg::Node> node = new osg::Node; // this is legal
    osg::Node node; // this is illegal!
  • A regular C++ pointer is still workable temporarily. But user applications should remember to assign it to osg::ref_ptr<> or add it to a scene graph element (almost all OSG scene classes use smart pointers to manage child objects) in the end, as it is always the safest approach.
    osg::Node* tmpNode = new osg::Node; // this is OK
    …
    osg::ref_ptr<osg::Node> node = tmpNode; // Good finish!
  • Don't play with reference cycles, as the garbage collecting mechanism cannot handle it. A reference cycle means that an object refers to itself directly or indirectly, which leads to an incorrect calculation of the referenced counting number.

The scene graph shown in the following image contains two kinds of reference cycles, which are both invalid. The node Child 1.1 directly adds itself as the child node and will form a dead cycle while traversing to its children, because it is the child of itself, too! The node Child 2.2, which also makes a reference cycle indirectly, will cause the same problem while running:

Collecting garbage: why and how

Now let's have a better grasp of the basic concepts of memory management, through a very simple example.

主站蜘蛛池模板: 青冈县| 托克逊县| 兴化市| 湘潭县| 韶关市| 揭阳市| 孟连| 高唐县| 衡阳县| 安化县| 苍溪县| 霍林郭勒市| 手游| 瑞安市| 务川| 揭阳市| 保德县| 深泽县| 江永县| 内黄县| 富宁县| 松江区| 乐山市| 沙田区| 宜黄县| 江达县| 萨迦县| 榆林市| 井冈山市| 颍上县| 都兰县| 临泽县| 益阳市| 伽师县| 栾城县| 鄢陵县| 民权县| 天津市| 西充县| 车险| 贺兰县|