An implicit memory leak brought by dictionary

Source: Internet
Author: User

Beware of an implicit memory leak caused by dictionary

Recently, when looking at the source code of the dictionary, suddenly think of the improper use of dictionary there is a possibility of a hidden memory leak.

Simplifying usage scenarios

Little A is writing a simple book sales system.

The first thing he needs to deal with is the collection of books and orders. Then he found himself needing a specific memory structure to temporarily save all the orders and their accompanying collection of sales books to reduce the pressure on the database. Small a think of the dictionary dictionary the best structure to save the associated data-the order object as a key, the corresponding sales bibliography books as a value, saved in the dictionary.

The order contains the order ID/order Person ID/order time. Little a knows that to use the order object as a key, he must rewrite the GetHashCode () method of the Order class and The Equals () method so that the two functions make sense rather than accept the default implementation of the system, which is required by dictionary. This feature is implemented as follows:

Order Class
  1. Internal class Order
  2. {
  3. public int ID {get; set;}
  4. public int Patronid {get; set;}
  5. Public DateTime boughttime {get; set;}
  6. // ...
  7. public override bool Equals (object obj)
  8. {
  9. if (obj = = null)
  10. {
  11. return false;
  12. }
  13. Order Ordertocompare = obj as order;
  14. if (Ordertocompare = = null)
  15. {
  16. return false;
  17. }
  18. return ID = = Ordertocompare.id &&
  19. Patronid = = Ordertocompare.patronid &&
  20. Boughttime = = Ordertocompare.boughttime;
  21. }
  22. public override int GetHashCode ()
  23. {
  24. return ("ID" + ID.) ToString () +
  25. "Patronid" + patronid.tostring () +
  26. "TimeStamp" + boughttime.tostring ())
  27. . GetHashCode ();
  28. }
  29. }

Later, he found that for some orders that already existed, if there were any user changes to the purchased books, the orders needed to be updated, and the timestamp of the order would need to be updated after the update:

Update Order Property
    1. public void Updateordertime (order order)
    2. {
    3. Order. Boughttime = DateTime.Now;
    4. }

This simple system has just sent to the quality department after the test for two days, the boss put small a called to the eyes of the has penny, "Memory leak!"

What is the problem?

The problem is with the order object as the dictionary key.

The dictionary. NET implementation has an implicit feature that is easier to overlook, which is how it locates the stored data. Dictionary is calculated by hashing the hash value of the key to determine where its corresponding value is stored. The Add/delete/modify operations within dictionary are completely dependent on this positioning method. This positioning method is embodied in the dictionary source code as a findentry () operation:

  1. private int findentry (TKey key) {
  2. if (key = = null) {
  3. Throwhelper.throwargumentnullexception (Exceptionargument.key);
  4. }
  5. if (buckets! = null) {
  6. int hashcode = comparer. GetHashCode (key) & 0x7FFFFFFF;
  7. for (int i = buckets[hashcode% buckets. Length]; I >= 0; i = entries[i].next) {
  8. if (Entries[i].hashcode = = Hashcode && comparer. Equals (Entries[i].key, key)) return I;
  9. }
  10. }
  11. return-1;
  12. }

When the Boughttime property of an order changes, the hash value of the corresponding order is changed, and the list of books accompanying the order is still in dictionary, but the Findentry () operation is not able to locate it. This list of bibliographies will remain in the dictionary until the end of the dictionary life cycle. This is an implicit memory leak. If this is a WinForm program, perhaps the impact is not very large. However, if a network service that requires high online rates is used, the memory usage of overflow exceptions will certainly be unavoidable.

Memory leaks In this simple scenario can be more subtle and more difficult to spot in more complex scenarios. Although the basic rationale is the same, in more complex business logic, we may be more likely to ignore its harm.

Conclusion

If a business object may be modified in the business logic, do not use it as a dictionary key!!! When using objects as keys to dictionary, it is prudent to consider whether the object will be implicitly or explicitly changed in the rest of the way.

Proper use of dictionary.

An implicit memory leak brought by dictionary

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.