Avoid Poor Allocation Pattern

Please follow this template to help us specify this new rule:

  • description of the Rule. Why
    Poor memory allocation patterns may cause the garbage collector to spend most of its time collecting objects from Generation 2. Collecting objects from Generation 2 leads to poor application performance and high loads on the CPU.
    When
    This is an important guideline and should be followed before deploying the application in production.
    How
    You can profile the memory allocation pattern by using code profiling tools. You need to check for the following in the allocation pattern:

    The percentage of allocations in Gen 0, Gen 1, and Gen 2. If the percentage of objects in Gen 2 is high, the resource cleanup in the application block is not efficient and there are memory leaks. This probably means the objects are held up longer than required (this may be expected in some scenarios). Profiling the application gives you an idea of the type of objects that are being promoted to Gen 2 of the heap. You can then focus on analyzing the culprit code snippet and rectify the problem. An efficient allocation pattern should have most of the allocations in Gen 0 and Gen 1 over a period of time. There might be certain objects, such as a pinned pool of reusable buffers used for I/O work, that are promoted to Gen 2 when the application starts. The faster this pool of buffers gets promoted to Gen 2, the better.

    The fragmentation of the heap. The heap fragmentation happens most often in scenarios where the objects are pinned and cannot be moved. The memory cannot be efficiently compacted around these objects. The longer these objects are pinned, the greater the chances of heap fragmentation. As mentioned earlier, there might be a pool of buffers that needs to be used for I/O calls. If these objects are initialized when the application starts, they quickly move the Gen 2, where the overhead of heap allocation is largely removed.

    “Side effect” allocations. Large number of side effect allocations take place because of some calls in a loop or recursive functions, such as the calls to string-related functions String.ToLower() or concatenation using the + operator happening in a loop. This causes the original string to be discarded and a new string to be allocated for each such operation. These operations in a loop may cause significant increase in memory consumption.

  • snippet of Noncompliant Code
    12 Calls to String.Concat detected. Evaluate the use of this method to measure the impact on memory.

  • snippet of Compilant Code (fixing the above noncompliant code)

  • exceptions to the Noncompliant Code, i.e. conditions in which the noncompliant code should not raise an issue so that we reduce the number of False Positives.

  • external references and/or language specifications
    Chapter 5 - Improving Managed Code Performance
    Debugging Memory Problems

  • type : Bug

  • Tags

Guidelines:
We want to add as many valuable rules as possible. Thus we have guidelines to help us see the value of a rule and decide if it should be implemented. Please read them before submitting your rule:

  • Is the rule useful for a developer.
    • If the rule is a Bug, Code Smell or Vulnerability it should ask the developer to fix a real problem. It shouldn’t raise warnings asking for a manual review.