1 / 31

CS4723 Software Validation and Quality Assurance

CS4723 Software Validation and Quality Assurance. Lecture 12 Common Bug Patterns-Performance. Major Performance Concerns. Time efficiency Useless function executions In-efficient API invocations Improper parallel execution Memory efficiency Memory Leaks Unused code / data. 2.

Télécharger la présentation

CS4723 Software Validation and Quality Assurance

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CS4723Software Validation and Quality Assurance Lecture 12 Common Bug Patterns-Performance

  2. Major Performance Concerns Time efficiency Useless function executions In-efficient API invocations Improper parallel execution Memory efficiency Memory Leaks Unused code / data 2

  3. Useless function executions 3

  4. Useless function executions 4

  5. In-efficient API invocations 5

  6. In-efficient API invocations 6

  7. In-efficient API invocations SBSC: Method concatenates strings using + in a loop Bad: String s = ""; for (int i = 0; i < field.length; ++i) { s = s + field[i]; } Better: StringBuffer buf = new StringBuffer(); for (int i = 0; i < field.length; ++i) { buf.append(field[i]); } String s = buf.toString(); 7

  8. Improper parallel execution 8

  9. Enhancing Time Efficiency Focus on the frequently executed part of the code Sometimes need to use profilers to find it Adding guard to code that is not always required Understand the performance specification of API methods (i.e., what the method actually does) Be careful of redundant locks in concurrency 9

  10. Major Performance Concerns Time efficiency Useless function executions In-efficient API invocations Improper parallel execution Memory efficiency Memory Leaks Unused code / data 10

  11. Memory Leaks A memory leak is said to have occurred when: • the last pointer to a malloc'd object is reset or • the last pointer to a malloc'd object is a local variable in a function from which a return is made. In these cases the malloc'd memory is no longer accessible. Excessive leaking can lead to poor performance and, in the extreme, program failure.

  12. Memory Leaks Programmers must recognize when the last pointer to malloc'd storage is about to be lost and use the free() function call to release the storage before it becomes impossible to do so.

  13. Problem 1: the instant leak This is an example of an instant leak. The memory is allocated at the time temp is declared and leaked when temp is reassigned the address of the first object in the list. int *temp = (int *) malloc(N * sizeof(int)); temp = list->head; while (temp != NULL) -- process list of objects -- Two possible solutions: • Insert free(temp) before temp = list->head; This eliminates the leak, but what benefit is there to allocating storage and instantly freeing it???

  14. Problem 1: the instant leak (cont'd) Possible solution: • Instead of allocating memory for temp change the declaration to obj_t *temp = NULL; This is the correct solution Rules of thumb: • A rational rule of thumb is never malloc memory unless you are going to write into it! • Another good rule of thumb is to never declare a pointer without initializing it.

  15. Problem 2: The traditional leak • In this traditional leak, storage is also allocated for univec at the time it is declared. • The call to vl_unitvec3() writes into that storage. • If the storage is not malloc'd, then univec will not point to anything useful and the call to vl_unitvec3() will produce a seg-fault or will overwrite some other part of the program's data. So this malloc() is necessary. { double *univec = malloc(3 * sizeof(double)); vl_unitvec3(dir, univec); : more stuff involving univec : return; }

  16. Problem 2: The traditional leak { double *univec = malloc(3 * sizeof(double)); vl_unitvec3(dir, univec); : more stuff involving univec : return; } • Although this malloc is necessary, the instant the return statement is executed, the value of univec becomes no longer accessible and the memory has been leaked. • The correct solution is to add free(univec); just before the return;

  17. Problem 2: The traditional leak • A rational rule of thumb is: malloc'd storage must be freed before the last pointer to it is lost.

  18. Problem 3: Overcompensation • The concern about leakage might lead to an overcompensation. For example, an object loader might do the following: obj_t *new_obj; : new_obj = malloc(sizeof(obj_t)); : if (list->head == NULL) { list->head = list->tail = new_obj; } else { list->tail->next = new_obj; list->tail = new_obj; } free(new_obj);

  19. Problem 3: Overcompensation obj_t *new_obj; : if (…) : else { list->tail->next = new_obj; list->tail->next = malloc(…) list->tail = new_obj; } free(new_obj); • This problem is the reverse of a memory leak . A live pointer to the object exists through the list structure, but the storage has been freed.

  20. Problem 3: Overcompensation else { list->tail->next = new_obj; list->tail = new_obj; } free(new_obj); The results of this are: • Usually attempts to reference the freed storage will succeed. • The storage will eventually be assigned to another object in a later call to malloc(). • Then “both” objects will occupy the same storage.

  21. Problem 3: Overcompensation else { list->tail->next = new_obj; list->tail = new_obj; } free(new_obj); Rational rule of thumb: Never free an object while live pointers to the object exist. Any pointers to the freed storage that exist after the return from free() should be set to NULL. To fix this problem, the free(new_obj) must be deleted from the code. If the objects in the object list are to be freed, it is safe to do so only at the end of processing. It is not imperative to do so at that point because the Operating System will reclaim all memory used by the process when the program exits.

  22. Problem 3a: Overcompensation revisited • Overcompensation may cause memory leaks head = malloc(…) head->next = malloc(…) free(head) The the memory block head->next points to will be lost.

  23. Problem 3b: Overcompensation revisited The free() function must be used onlyto free memory previously allocated by malloc() unsigned char buf[256]; : : free(buf); is a fatal error.

  24. Problem 3b: Overcompensation revisited • The free() function must not be used to free the same area twice. buf = (unsigned char *)malloc(256); : free(buf); : free(buf); is also a fatal error.

  25. General Solution to Freeing Memory • Even for some complicated programs, it is usually easy for an experienced programmer to know when to free() dynamically allocated storage. • In programs as complicated as the Linux kernel it is not. • A technique known as reference counting is used.

  26. General Solution to Freeing Memory typedefstructobj_type { int refcount; : : } obj_t; At object creation time: new_obj = malloc(sizeof(obj_t)); new_obj->refcount = 1; When a new reference to the object is created my_new_ptr = new_obj; my_new_ptr->refcount += 1;

  27. General Solution to Freeing Memory When a reference is about to be reused or lost my_new_ptr->refcount -= 1; if (my_new_ptr->refcount == 0) free(my_new_ptr); my_new_ptr = NULL; In a multithreaded environment, such as in an OS kernel, it is mandatory that the testing and update of the reference counter be done atomically.

  28. Java Memory Leak Memory leaks still exist in Java !! Lost objects: unreachable but not freed Useless objects: reachable but not used again A Java memory leak can also cause severe problems Performance degradation OutofMemory exception

  29. Java Memory Leak Example You initialized a large data structure, but only use it at the beginning. public static void main(String args[]){ List<String> lines = loadFile(“/path/to/largefile”); String key = find(lines); do_some_thing (key); … }

  30. Unused Fields Class fields are the major elements that occupy system memory Class fields may have huge number of copies at runtime Objects of subclass often contains all fields of the super classes Objects are sometimes fakely used (e.g., only has a getter) Box types consume much more memory than primitive fields

  31. Enhancing Memory Efficiency Avoid memory leak Empty large maps and lists when they are no longer required Understand the memory consumption of objects. Checking for unused fields 31

More Related