diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp
index f29814efed610..4e575c233db98 100644
--- a/src/hotspot/share/cds/filemap.cpp
+++ b/src/hotspot/share/cds/filemap.cpp
@@ -2187,7 +2187,8 @@ bool FileMapInfo::map_heap_region_impl() {
   }
 
   // allocate from java heap
-  if (!G1CollectedHeap::heap()->alloc_archive_regions(_mapped_heap_memregion)) {
+  uint regions_committed;
+  if (!G1CollectedHeap::heap()->alloc_archive_regions(_mapped_heap_memregion, regions_committed)) {
     log_info(cds)("Unable to allocate region, java heap range is already in use.");
     return false;
   }
@@ -2199,7 +2200,7 @@ bool FileMapInfo::map_heap_region_impl() {
                               addr, _mapped_heap_memregion.byte_size(), r->read_only(),
                               r->allow_exec());
   if (base == nullptr || base != addr) {
-    dealloc_heap_region();
+    dealloc_heap_region(regions_committed);
     log_info(cds)("UseSharedSpaces: Unable to map at required address in java heap. "
                   INTPTR_FORMAT ", size = " SIZE_FORMAT " bytes",
                   p2i(addr), _mapped_heap_memregion.byte_size());
@@ -2208,7 +2209,7 @@ bool FileMapInfo::map_heap_region_impl() {
 
   r->set_mapped_base(base);
   if (VerifySharedSpaces && !r->check_region_crc()) {
-    dealloc_heap_region();
+    dealloc_heap_region(regions_committed);
     log_info(cds)("mapped heap region is corrupt");
     return false;
   }
@@ -2251,8 +2252,8 @@ void FileMapInfo::fixup_mapped_heap_region() {
 }
 
 // dealloc the archive regions from java heap
-void FileMapInfo::dealloc_heap_region() {
-  G1CollectedHeap::heap()->dealloc_archive_regions(_mapped_heap_memregion);
+void FileMapInfo::dealloc_heap_region(uint regions_committed) {
+  G1CollectedHeap::heap()->dealloc_archive_regions(_mapped_heap_memregion, regions_committed);
 }
 #endif // INCLUDE_CDS_JAVA_HEAP
 
diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp
index 160f598796dfc..d773dfa70c77f 100644
--- a/src/hotspot/share/cds/filemap.hpp
+++ b/src/hotspot/share/cds/filemap.hpp
@@ -548,7 +548,7 @@ class FileMapInfo : public CHeapObj<mtInternal> {
   bool  validate_boot_class_paths() NOT_CDS_RETURN_(false);
   bool  validate_app_class_paths(int shared_app_paths_len) NOT_CDS_RETURN_(false);
   bool  map_heap_region_impl() NOT_CDS_JAVA_HEAP_RETURN_(false);
-  void  dealloc_heap_region() NOT_CDS_JAVA_HEAP_RETURN;
+  void  dealloc_heap_region(uint regions_committed) NOT_CDS_JAVA_HEAP_RETURN;
   bool  can_use_heap_region();
   bool  load_heap_region() NOT_CDS_JAVA_HEAP_RETURN_(false);
   bool  map_heap_region() NOT_CDS_JAVA_HEAP_RETURN_(false);
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
index eeaa54cee853a..353111ee58543 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
@@ -532,7 +532,7 @@ void G1CollectedHeap::iterate_regions_in_range(MemRegion range, const Func& func
   }
 }
 
-bool G1CollectedHeap::alloc_archive_regions(MemRegion range) {
+bool G1CollectedHeap::alloc_archive_regions(MemRegion range, uint& regions_committed) {
   assert(!is_init_completed(), "Expect to be called at JVM init time");
   MutexLocker x(Heap_lock);
 
@@ -547,7 +547,6 @@ bool G1CollectedHeap::alloc_archive_regions(MemRegion range) {
   HeapWord* start_address = range.start();
   size_t word_size = range.word_size();
   HeapWord* last_address = range.last();
-  size_t commits = 0;
 
   guarantee(reserved.contains(start_address) && reserved.contains(last_address),
             "MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]",
@@ -555,15 +554,16 @@ bool G1CollectedHeap::alloc_archive_regions(MemRegion range) {
 
   // Perform the actual region allocation, exiting if it fails.
   // Then note how much new space we have allocated.
-  if (!_hrm.allocate_containing_regions(range, &commits, workers())) {
+  regions_committed = 0;
+  uint regions_allocated = 0;
+  if (!_hrm.allocate_containing_regions(range, &regions_committed, &regions_allocated, workers())) {
     return false;
   }
   increase_used(word_size * HeapWordSize);
-  if (commits != 0) {
-    log_debug(gc, ergo, heap)("Attempt heap expansion (allocate archive regions). Total size: " SIZE_FORMAT "B",
-                              HeapRegion::GrainWords * HeapWordSize * commits);
 
-  }
+  log_debug(gc, ergo, heap)("Allocate CDS archive regions. Allocated %u Committed %u",
+                            regions_allocated, regions_committed);
+
 
   // Mark each G1 region touched by the range as old, add it to
   // the old set, and set top.
@@ -591,11 +591,11 @@ void G1CollectedHeap::populate_archive_regions_bot_part(MemRegion range) {
                            });
 }
 
-void G1CollectedHeap::dealloc_archive_regions(MemRegion range) {
+void G1CollectedHeap::dealloc_archive_regions(MemRegion range, uint regions_committed) {
   assert(!is_init_completed(), "Expect to be called at JVM init time");
   MemRegion reserved = _hrm.reserved();
   size_t size_used = 0;
-  uint shrink_count = 0;
+  uint regions_freed = 0;
 
   // Free the G1 regions that are within the specified range.
   MutexLocker x(Heap_lock);
@@ -607,21 +607,27 @@ void G1CollectedHeap::dealloc_archive_regions(MemRegion range) {
          p2i(start_address), p2i(last_address));
   size_used += range.byte_size();
 
-  // Free, empty and uncommit regions with CDS archive content.
+  // Free, empty and optionally uncommit regions with CDS archive content.
+  uint shrink_count = 0;
   auto dealloc_archive_region = [&] (HeapRegion* r, bool is_last) {
     guarantee(r->is_old(), "Expected old region at index %u", r->hrm_index());
     _old_set.remove(r);
-    r->set_free();
-    r->set_top(r->bottom());
-    _hrm.shrink_at(r->hrm_index(), 1);
-    shrink_count++;
+    free_region(r, nullptr);
+    regions_freed++;
+    if (regions_committed > shrink_count) {
+      _hrm.shrink_at(r->hrm_index(), 1);
+      shrink_count++;
+    } else {
+      _hrm.insert_into_free_list(r);
+      hr_printer()->cleanup(r);
+    }
   };
 
   iterate_regions_in_range(range, dealloc_archive_region);
 
-  if (shrink_count != 0) {
-    log_debug(gc, ergo, heap)("Attempt heap shrinking (CDS archive regions). Total size: " SIZE_FORMAT "B",
-                              HeapRegion::GrainWords * HeapWordSize * shrink_count);
+  log_debug(gc, ergo, heap)("Deallocate CDS archive regions. Freed %u Uncommitted %u regions.",
+                            regions_freed, regions_committed);
+  if (regions_committed != 0) {
     // Explicit uncommit.
     uncommit_regions(shrink_count);
   }
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
index e1b95bf616df9..d02b5e32406f6 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
@@ -714,7 +714,7 @@ class G1CollectedHeap : public CollectedHeap {
 
   // Commit the appropriate G1 region(s) containing the specified range
   // and mark them as 'old' region(s).
-  bool alloc_archive_regions(MemRegion range);
+  bool alloc_archive_regions(MemRegion range, uint& regions_committed);
 
   // Populate the G1BlockOffsetTablePart for archived regions with the given
   // memory range.
@@ -724,7 +724,7 @@ class G1CollectedHeap : public CollectedHeap {
   // which had been allocated by alloc_archive_regions. This should be called
   // at JVM init time if the archive heap's contents cannot be used (e.g., if
   // CRC check fails).
-  void dealloc_archive_regions(MemRegion range);
+  void dealloc_archive_regions(MemRegion range, uint regions_committed);
 
 private:
 
diff --git a/src/hotspot/share/gc/g1/heapRegionManager.cpp b/src/hotspot/share/gc/g1/heapRegionManager.cpp
index fc445142bd57b..5dbd604ec03bb 100644
--- a/src/hotspot/share/gc/g1/heapRegionManager.cpp
+++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp
@@ -551,8 +551,9 @@ uint HeapRegionManager::find_highest_free(bool* expanded) {
   return G1_NO_HRM_INDEX;
 }
 
-bool HeapRegionManager::allocate_containing_regions(MemRegion range, size_t* commit_count, WorkerThreads* pretouch_workers) {
-  size_t commits = 0;
+bool HeapRegionManager::allocate_containing_regions(MemRegion range, uint* commit_count, uint* allocate_count, WorkerThreads* pretouch_workers) {
+  uint commits = 0;
+  uint allocated = 0;
   uint start_index = (uint)_regions.get_index_by_address(range.start());
   uint last_index = (uint)_regions.get_index_by_address(range.last());
 
@@ -567,10 +568,12 @@ bool HeapRegionManager::allocate_containing_regions(MemRegion range, size_t* com
     if (!curr_region->is_free()) {
       return false;
     }
+    allocated++;
   }
 
   allocate_free_regions_starting_at(start_index, (last_index - start_index) + 1);
   *commit_count = commits;
+  *allocate_count = allocated;
   return true;
 }
 
diff --git a/src/hotspot/share/gc/g1/heapRegionManager.hpp b/src/hotspot/share/gc/g1/heapRegionManager.hpp
index ad985e1f85249..c1ef34e8b5872 100644
--- a/src/hotspot/share/gc/g1/heapRegionManager.hpp
+++ b/src/hotspot/share/gc/g1/heapRegionManager.hpp
@@ -263,8 +263,9 @@ class HeapRegionManager: public CHeapObj<mtGC> {
 
   // Allocate the regions that contain the address range specified, committing the
   // regions if necessary. Return false if any of the regions is already committed
-  // and not free, and return the number of regions newly committed in commit_count.
-  bool allocate_containing_regions(MemRegion range, size_t* commit_count, WorkerThreads* pretouch_workers);
+  // and not free, and return the number of regions newly committed in commit_count,
+  // allocated in allocate_count.
+  bool allocate_containing_regions(MemRegion range, uint* commit_count, uint* allocate_count, WorkerThreads* pretouch_workers);
 
   // Apply blk->do_heap_region() on all committed regions in address order,
   // terminating the iteration early if do_heap_region() returns true.