hotspot/src/share/vm/services/virtualMemoryTracker.cpp
changeset 38935 f7427b0e0d7c
parent 35483 d9cf65a7fd2d
child 40655 9f644073d3a0
equal deleted inserted replaced
38929:1ee62412a66f 38935:f7427b0e0d7c
    21  * questions.
    21  * questions.
    22  *
    22  *
    23  */
    23  */
    24 #include "precompiled.hpp"
    24 #include "precompiled.hpp"
    25 
    25 
       
    26 #include "runtime/atomic.inline.hpp"
       
    27 #include "runtime/os.hpp"
    26 #include "runtime/threadCritical.hpp"
    28 #include "runtime/threadCritical.hpp"
       
    29 #include "services/memTracker.hpp"
    27 #include "services/virtualMemoryTracker.hpp"
    30 #include "services/virtualMemoryTracker.hpp"
    28 
    31 
    29 size_t VirtualMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)];
    32 size_t VirtualMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)];
    30 
    33 
    31 void VirtualMemorySummary::initialize() {
    34 void VirtualMemorySummary::initialize() {
    50   assert(contain_region(addr, size), "Not contain this region");
    53   assert(contain_region(addr, size), "Not contain this region");
    51 
    54 
    52   if (all_committed()) return true;
    55   if (all_committed()) return true;
    53 
    56 
    54   CommittedMemoryRegion committed_rgn(addr, size, stack);
    57   CommittedMemoryRegion committed_rgn(addr, size, stack);
    55   LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.find_node(committed_rgn);
    58   LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.head();
    56   if (node != NULL) {
    59 
       
    60   while (node != NULL) {
    57     CommittedMemoryRegion* rgn = node->data();
    61     CommittedMemoryRegion* rgn = node->data();
    58     if (rgn->same_region(addr, size)) {
    62     if (rgn->same_region(addr, size)) {
    59       return true;
    63       return true;
    60     }
    64     }
    61 
    65 
    62     if (rgn->adjacent_to(addr, size)) {
    66     if (rgn->adjacent_to(addr, size)) {
    63       // check if the next region covers this committed region,
    67       // special case to expand prior region if there is no next region
    64       // the regions may not be merged due to different call stacks
    68       LinkedListNode<CommittedMemoryRegion>* next = node->next();
    65       LinkedListNode<CommittedMemoryRegion>* next =
    69       if (next == NULL && rgn->call_stack()->equals(stack)) {
    66         node->next();
       
    67       if (next != NULL && next->data()->contain_region(addr, size)) {
       
    68         if (next->data()->same_region(addr, size)) {
       
    69           next->data()->set_call_stack(stack);
       
    70         }
       
    71         return true;
       
    72       }
       
    73       if (rgn->call_stack()->equals(stack)) {
       
    74         VirtualMemorySummary::record_uncommitted_memory(rgn->size(), flag());
    70         VirtualMemorySummary::record_uncommitted_memory(rgn->size(), flag());
    75         // the two adjacent regions have the same call stack, merge them
    71         // the two adjacent regions have the same call stack, merge them
    76         rgn->expand_region(addr, size);
    72         rgn->expand_region(addr, size);
    77         VirtualMemorySummary::record_committed_memory(rgn->size(), flag());
    73         VirtualMemorySummary::record_committed_memory(rgn->size(), flag());
    78         return true;
    74         return true;
    79       }
    75       }
    80       VirtualMemorySummary::record_committed_memory(size, flag());
    76       }
    81       if (rgn->base() > addr) {
    77 
    82         return _committed_regions.insert_before(committed_rgn, node) != NULL;
    78     if (rgn->overlap_region(addr, size)) {
    83       } else {
    79       // Clear a space for this region in the case it overlaps with any regions.
    84         return _committed_regions.insert_after(committed_rgn, node) != NULL;
    80       remove_uncommitted_region(addr, size);
    85       }
    81       break;  // commit below
    86     }
    82     }
    87     assert(rgn->contain_region(addr, size), "Must cover this region");
    83     if (rgn->end() >= addr + size){
    88     return true;
    84       break;
    89   } else {
    85     }
       
    86     node = node->next();
       
    87   }
       
    88 
    90     // New committed region
    89     // New committed region
    91     VirtualMemorySummary::record_committed_memory(size, flag());
    90     VirtualMemorySummary::record_committed_memory(size, flag());
    92     return add_committed_region(committed_rgn);
    91     return add_committed_region(committed_rgn);
    93   }
    92   }
    94 }
       
    95 
    93 
    96 void ReservedMemoryRegion::set_all_committed(bool b) {
    94 void ReservedMemoryRegion::set_all_committed(bool b) {
    97   if (all_committed() != b) {
    95   if (all_committed() != b) {
    98     _all_committed = b;
    96     _all_committed = b;
    99     if (b) {
    97     if (b) {
   173           return false;
   171           return false;
   174         }
   172         }
   175       }
   173       }
   176     }
   174     }
   177   } else {
   175   } else {
   178     // we have to walk whole list to remove the committed regions in
   176     CommittedMemoryRegion del_rgn(addr, sz, *call_stack());
   179     // specified range
   177     address end = addr + sz;
   180     LinkedListNode<CommittedMemoryRegion>* head =
   178 
   181       _committed_regions.head();
   179     LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head();
   182     LinkedListNode<CommittedMemoryRegion>* prev = NULL;
   180     LinkedListNode<CommittedMemoryRegion>* prev = NULL;
   183     VirtualMemoryRegion uncommitted_rgn(addr, sz);
   181     CommittedMemoryRegion* crgn;
   184 
   182 
   185     while (head != NULL && !uncommitted_rgn.is_empty()) {
   183     while (head != NULL) {
   186       CommittedMemoryRegion* crgn = head->data();
   184       crgn = head->data();
   187       // this committed region overlaps to region to uncommit
   185 
   188       if (crgn->overlap_region(uncommitted_rgn.base(), uncommitted_rgn.size())) {
   186       if (crgn->same_region(addr, sz)) {
   189         if (crgn->same_region(uncommitted_rgn.base(), uncommitted_rgn.size())) {
   187         VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
   190           // find matched region, remove the node will do
       
   191           VirtualMemorySummary::record_uncommitted_memory(uncommitted_rgn.size(), flag());
       
   192           _committed_regions.remove_after(prev);
   188           _committed_regions.remove_after(prev);
   193           return true;
   189           return true;
   194         } else if (crgn->contain_region(uncommitted_rgn.base(), uncommitted_rgn.size())) {
   190       }
   195           // this committed region contains whole uncommitted region
   191 
   196           VirtualMemorySummary::record_uncommitted_memory(uncommitted_rgn.size(), flag());
   192       // del_rgn contains crgn
   197           return remove_uncommitted_region(head, uncommitted_rgn.base(), uncommitted_rgn.size());
   193       if (del_rgn.contain_region(crgn->base(), crgn->size())) {
   198         } else if (uncommitted_rgn.contain_region(crgn->base(), crgn->size())) {
       
   199           // this committed region has been uncommitted
       
   200           size_t exclude_size = crgn->end() - uncommitted_rgn.base();
       
   201           uncommitted_rgn.exclude_region(uncommitted_rgn.base(), exclude_size);
       
   202           VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
   194           VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
   203           LinkedListNode<CommittedMemoryRegion>* tmp = head;
       
   204           head = head->next();
   195           head = head->next();
   205           _committed_regions.remove_after(prev);
   196           _committed_regions.remove_after(prev);
   206           continue;
   197         continue;  // don't update head or prev
   207         } else if (crgn->contain_address(uncommitted_rgn.base())) {
       
   208           size_t toUncommitted = crgn->end() - uncommitted_rgn.base();
       
   209           crgn->exclude_region(uncommitted_rgn.base(), toUncommitted);
       
   210           uncommitted_rgn.exclude_region(uncommitted_rgn.base(), toUncommitted);
       
   211           VirtualMemorySummary::record_uncommitted_memory(toUncommitted, flag());
       
   212         } else if (uncommitted_rgn.contain_address(crgn->base())) {
       
   213           size_t toUncommitted = uncommitted_rgn.end() - crgn->base();
       
   214           crgn->exclude_region(crgn->base(), toUncommitted);
       
   215           uncommitted_rgn.exclude_region(uncommitted_rgn.end() - toUncommitted,
       
   216             toUncommitted);
       
   217           VirtualMemorySummary::record_uncommitted_memory(toUncommitted, flag());
       
   218         }
   198         }
   219       }
   199 
       
   200       // Found addr in the current crgn. There are 2 subcases:
       
   201       if (crgn->contain_address(addr)) {
       
   202 
       
   203         // (1) Found addr+size in current crgn as well. (del_rgn is contained in crgn)
       
   204         if (crgn->contain_address(end - 1)) {
       
   205           VirtualMemorySummary::record_uncommitted_memory(sz, flag());
       
   206           return remove_uncommitted_region(head, addr, sz); // done!
       
   207         } else {
       
   208           // (2) Did not find del_rgn's end in crgn.
       
   209           size_t size = crgn->end() - del_rgn.base();
       
   210           crgn->exclude_region(addr, size);
       
   211           VirtualMemorySummary::record_uncommitted_memory(size, flag());
       
   212       }
       
   213 
       
   214       } else if (crgn->contain_address(end - 1)) {
       
   215       // Found del_rgn's end, but not its base addr.
       
   216         size_t size = del_rgn.end() - crgn->base();
       
   217         crgn->exclude_region(crgn->base(), size);
       
   218         VirtualMemorySummary::record_uncommitted_memory(size, flag());
       
   219         return true;  // should be done if the list is sorted properly!
       
   220       }
       
   221 
   220       prev = head;
   222       prev = head;
   221       head = head->next();
   223       head = head->next();
   222     }
   224     }
   223   }
   225   }
   224 
   226 
   384   ReservedMemoryRegion  rgn(addr, size);
   386   ReservedMemoryRegion  rgn(addr, size);
   385   ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
   387   ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
   386 
   388 
   387   assert(reserved_rgn != NULL, "No reserved region");
   389   assert(reserved_rgn != NULL, "No reserved region");
   388   assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
   390   assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
   389   return reserved_rgn->add_committed_region(addr, size, stack);
   391   bool result = reserved_rgn->add_committed_region(addr, size, stack);
       
   392   return result;
   390 }
   393 }
   391 
   394 
   392 bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) {
   395 bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) {
   393   assert(addr != NULL, "Invalid address");
   396   assert(addr != NULL, "Invalid address");
   394   assert(size > 0, "Invalid size");
   397   assert(size > 0, "Invalid size");
   396 
   399 
   397   ReservedMemoryRegion  rgn(addr, size);
   400   ReservedMemoryRegion  rgn(addr, size);
   398   ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
   401   ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
   399   assert(reserved_rgn != NULL, "No reserved region");
   402   assert(reserved_rgn != NULL, "No reserved region");
   400   assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
   403   assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
   401   return reserved_rgn->remove_uncommitted_region(addr, size);
   404   bool result = reserved_rgn->remove_uncommitted_region(addr, size);
       
   405   return result;
   402 }
   406 }
   403 
   407 
   404 bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) {
   408 bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) {
   405   assert(addr != NULL, "Invalid address");
   409   assert(addr != NULL, "Invalid address");
   406   assert(size > 0, "Invalid size");
   410   assert(size > 0, "Invalid size");
   486     }
   490     }
   487   }
   491   }
   488 
   492 
   489   return true;
   493   return true;
   490 }
   494 }
   491 
       
   492