diff --git a/Control/AthContainers/AthContainers/DataVector.h b/Control/AthContainers/AthContainers/DataVector.h
index 37e4ae0a045e8a372374d405281ada661ec12643..9bc8775a4384e2825b0e7c10f5bff94442adf561 100644
--- a/Control/AthContainers/AthContainers/DataVector.h
+++ b/Control/AthContainers/AthContainers/DataVector.h
@@ -837,6 +837,9 @@ public:
   typedef DataVector base_data_vector;
 
 
+  using Deleter = typename BASE::Deleter;
+
+
   //========================================================================
   /** @name Constructors, destructors, assignment. */
   //@{
@@ -1710,6 +1713,20 @@ public:
               SG::IndexTrackingPolicy trackIndices);
 
 
+  /**
+   * @brief Erase all the elements in the collection, and change 
+   *        how elements are to be deleted.
+   * @param deleter Object to be used to delete object.
+   *                Passing nullptr will change back to the default.
+   *
+   * If the container owns its elements, then the removed elements
+   * will be deleted.  Any duplicates will be removed in this process,
+   * but don't rely on this.
+   * After the current elements are deleted, the Deleter object is changed.
+   */
+  void clear (std::unique_ptr<Deleter> deleter);
+
+
   /**
    * @brief Return the DV/DL info struct for this class.
    *
@@ -2046,6 +2063,22 @@ public:
 
   typedef DataVector base_data_vector;
 
+
+  /**
+   * @brief Interface to allow customizing how elements are to be deleted.
+   */
+  class Deleter
+  {
+  public:
+    using value_type = DataVector::value_type;
+    using PtrVector = DataVector::PtrVector;
+    virtual ~Deleter() = default;
+    virtual void doDelete (value_type p) = 0;
+    virtual void doDelete (typename PtrVector::iterator first,
+                           typename PtrVector::iterator last) = 0;
+  };
+
+
   //========================================================================
   /** @name Constructors, destructors, assignment. */
   //@{
@@ -2920,6 +2953,20 @@ public:
               SG::IndexTrackingPolicy trackIndices);
 
 
+  /**
+   * @brief Erase all the elements in the collection, and change 
+   *        how elements are to be deleted.
+   * @param deleter Object to be used to delete object.
+   *                Passing nullptr will change back to the default.
+   *
+   * If the container owns its elements, then the removed elements
+   * will be deleted.  Any duplicates will be removed in this process,
+   * but don't rely on this.
+   * After the current elements are deleted, the Deleter object is changed.
+   */
+  void clear (std::unique_ptr<Deleter> deleter);
+
+
   /**
    * @brief Return the DV/DL info struct for this class.
    *
@@ -3146,6 +3193,22 @@ protected:
              typename PtrVector::iterator last);
 
 
+  /**
+   * @brief Delete an element
+   * @param p The element to delete.
+   */
+  void doDelete (value_type p);
+
+
+  /**
+   * @brief Delete a range of elements
+   * @param first Start of range to delete.
+   * @param last End of range to delete.
+   */
+  void doDelete (typename PtrVector::iterator first,
+                 typename PtrVector::iterator last);
+
+
 protected:
   /// The ownership policy of this container ---
   /// either SG::OWNS_ELEMENTS or SG::VIEW_ELEMENTS.
@@ -3154,6 +3217,12 @@ protected:
   /// This actually holds the elements.
   PtrVector m_pCont;
 
+  /// Interface telling us how to delete objects.
+  /// If null, just use the C++ default.
+  // This should really be a unique_ptr --- but that causes problems
+  // with ROOT persistency (even though this is tagged as transient).
+  Deleter* m_deleter = nullptr;
+
 
   /**
    * @brief Clear @c m_isMostDerived for this instance and for all bases.
@@ -3261,6 +3330,7 @@ public:
 #endif  
    /// Declare the automatically created variable transient
    ROOT_SELECTION_NS::MemberAttributes< kTransient > m_isMostDerived;
+   ROOT_SELECTION_NS::MemberAttributes< kTransient > m_deleter;
 
 };
 
diff --git a/Control/AthContainers/AthContainers/DataVector.icc b/Control/AthContainers/AthContainers/DataVector.icc
index 59db0982ae16e0781d50d213b2a8975c7385c78b..b5518a0624ad0644573cae4daa56949190a96d21 100644
--- a/Control/AthContainers/AthContainers/DataVector.icc
+++ b/Control/AthContainers/AthContainers/DataVector.icc
@@ -77,6 +77,7 @@ struct VirtBases<B1, DataModel_detail::NoBase, DataModel_detail::NoBase>
   typedef typename DataVector<B1>::size_type size_type;
   typedef typename DataVector<B1>::difference_type difference_type;
   typedef typename DataVector<B1>::allocator_type allocator_type;
+  typedef typename DataVector<B1>::Deleter Deleter;
 
   // We're using virtual derivation.
   static const bool has_virtual = true;
@@ -154,6 +155,7 @@ struct VirtBases<B1, B2, DataModel_detail::NoBase>
   typedef typename DataVector<B1>::size_type size_type;
   typedef typename DataVector<B1>::difference_type difference_type;
   typedef typename DataVector<B1>::allocator_type allocator_type;
+  typedef typename DataVector<B1>::Deleter Deleter;
 
   // We're using virtual derivation.
   static const bool has_virtual = true;
@@ -240,6 +242,7 @@ struct VirtBases
   typedef typename DataVector<B1>::size_type size_type;
   typedef typename DataVector<B1>::difference_type difference_type;
   typedef typename DataVector<B1>::allocator_type allocator_type;
+  typedef typename DataVector<B1>::Deleter Deleter;
 
   // We're using virtual derivation.
   static const bool has_virtual = true;
@@ -409,6 +412,8 @@ DataVector<T, BASE>::DataVector (DataVector&& rhs) noexcept
   SG::AuxVectorBase::operator= (std::move (rhs));
   this->m_ownPolicy = rhs.m_ownPolicy;
   this->m_pCont = std::move (rhs.m_pCont);
+  this->m_deleter = std::move(rhs.m_deleter);
+  rhs.m_deleter = nullptr;
 
   // Need to reset the container pointer on elements.
   this->setIndices (this->begin(), this->end());
@@ -551,6 +556,10 @@ DataVector<T, BASE>::operator= (DataVector<T, BASE>&& rhs) noexcept
     this->m_ownPolicy = rhs.m_ownPolicy;
     this->m_pCont = std::move (rhs.m_pCont);
 
+    delete this->m_deleter;
+    this->m_deleter = std::move(rhs.m_deleter);
+    rhs.m_deleter = nullptr;
+
     // Need to reset the container pointer on elements.
     this->setIndices (this->begin(), this->end());
   }
@@ -1369,7 +1378,7 @@ void DataVector<T, BASE>::pop_back()
 {
   if (!this->m_pCont.empty()) {
     if (this->m_ownPolicy == SG::OWN_ELEMENTS)
-      delete this->m_pCont.back();
+      this->doDelete (this->m_pCont.back());
     else
       this->clearIndex (iterator (this->m_pCont.end() - 1, this));
     this->m_pCont.pop_back();
@@ -1420,6 +1429,7 @@ void DataVector<T, BASE>::swap(DataVector& rhs)
   std::swap(this->m_ownPolicy, rhs.m_ownPolicy);
   SG::AuxVectorBase::swap (rhs);
   this->m_pCont.swap(rhs.m_pCont);
+  std::swap (this->m_deleter, rhs.m_deleter);
   this->setIndices (this->begin(), this->end());
   rhs.setIndices (rhs.begin(), rhs.end());
 }
@@ -1670,6 +1680,26 @@ const DataModel_detail::DVLInfoBase& DataVector<T, BASE>::dvlinfo()
 }
 
 
+/**
+ * @brief Erase all the elements in the collection, and change 
+ *        how elements are to be deleted.
+ * @param deleter Object to be used to delete object.
+ *                Passing nullptr will change back to the default.
+ *
+ * If the container owns its elements, then the removed elements
+ * will be deleted.  Any duplicates will be removed in this process,
+ * but don't rely on this.
+ * After the current elements are deleted, the Deleter object is changed.
+ */
+template <class T, class BASE>
+void DataVector<T, BASE>::clear (std::unique_ptr<Deleter> deleter)
+{
+  this->clear();
+  delete this->m_deleter;
+  this->m_deleter = deleter.release();
+}
+
+
 /**
  * @brief Return the DV/DL info struct for this class.
  *
@@ -1815,7 +1845,7 @@ void DataVector<T, BASE>::assignElement (typename BaseContainer::iterator pos,
 {
   testInsert ("assignElement");
   if (this->m_ownPolicy == SG::OWN_ELEMENTS)
-    delete *pos;
+    this->doDelete (*pos);
   else
     this->clearIndex (iterator (pos, this));
   *pos = newElem;
@@ -1841,7 +1871,7 @@ DataVector<T, BASE>::assignElement (typename BaseContainer::iterator pos,
     SG::throwExcNonowningContainer();
 
   testInsert ("assignElement");
-  delete *pos;
+  this->doDelete (*pos);
   value_type ptr = newElem.release();
   *pos = ptr;
   this->moveAux (pos - this->m_pCont.begin(), ptr);
@@ -1863,7 +1893,7 @@ DataVector<T, BASE>::assignBaseElement (typename BaseContainer::iterator pos,
 {
   testInsert ("assignBaseElement");
   if (this->m_ownPolicy == SG::OWN_ELEMENTS)
-    delete *pos;
+    this->doDelete (*pos);
   else
     this->clearIndex (iterator (pos, this));
   *pos = newElem;
@@ -2058,6 +2088,9 @@ DATAVECTOR::DataVector(DataVector&& rhs) noexcept
     m_ownPolicy(rhs.m_ownPolicy),
     m_pCont(std::move (rhs.m_pCont))
 {
+  m_deleter = std::move(rhs.m_deleter);
+  rhs.m_deleter = nullptr;
+
   // Need to reset the container pointer on elements.
   this->setIndices (this->begin(), this->end());
 
@@ -2172,6 +2205,10 @@ DATAVECTOR& DATAVECTOR::operator= (DATAVECTOR&& rhs) noexcept
     this->m_ownPolicy = rhs.m_ownPolicy;
     this->m_pCont = std::move (rhs.m_pCont);
 
+    delete this->m_deleter;
+    this->m_deleter = std::move(rhs.m_deleter);
+    rhs.m_deleter = nullptr;
+
     // Need to reset the container pointer on elements.
     this->setIndices (this->begin(), this->end());
   }
@@ -2250,10 +2287,9 @@ DATAVECTOR::~DataVector()
   if (m_ownPolicy == SG::OWN_ELEMENTS) {
     typename PtrVector::iterator new_end =
       DataVector_detail::remove_duplicates(m_pCont.begin(), m_pCont.end());
-    typename PtrVector::iterator iter = m_pCont.begin();
-    while (iter != new_end)
-      delete *(iter++);
-    }
+    this->doDelete (m_pCont.begin(), new_end);
+  }
+  delete m_deleter;
 }
 
 
@@ -3063,7 +3099,7 @@ void DATAVECTOR::pop_back()
 {
   if (!m_pCont.empty()) {
     if (m_ownPolicy == SG::OWN_ELEMENTS)
-      delete m_pCont.back();
+      this->doDelete (m_pCont.back());
     else
       this->clearIndex (m_pCont.end() - 1);
     m_pCont.pop_back();
@@ -3114,6 +3150,7 @@ void DATAVECTOR::swap(DataVector& rhs)
   std::swap(m_ownPolicy, rhs.m_ownPolicy);
   SG::AuxVectorBase::swap (rhs);
   m_pCont.swap(rhs.m_pCont);
+  std::swap (this->m_deleter, rhs.m_deleter);
   this->setIndices (this->begin(), this->end());
   rhs.setIndices (rhs.begin(), rhs.end());
 }
@@ -3388,6 +3425,27 @@ const DataModel_detail::DVLInfoBase& DATAVECTOR::dvlinfo()
 }
 
 
+/**
+ * @brief Erase all the elements in the collection, and change 
+ *        how elements are to be deleted.
+ * @param deleter Object to be used to delete object.
+ *                (The DataVector does not take ownership.)
+ *                Passing nullptr will change back to the default.
+ *
+ * If the container owns its elements, then the removed elements
+ * will be deleted.  Any duplicates will be removed in this process,
+ * but don't rely on this.
+ * After the current elements are deleted, the Deleter object is changed.
+ */
+template <class T>
+void DATAVECTOR::clear (std::unique_ptr<Deleter> deleter)
+{
+  this->clear();
+  delete this->m_deleter;
+  this->m_deleter = deleter.release();
+}
+
+
 /**
  * @brief Return the DV/DL info struct for this class.
  *
@@ -3492,7 +3550,7 @@ void DATAVECTOR::assignElement (typename BaseContainer::iterator pos,
 {
   testInsert ("assignElement");
   if (this->m_ownPolicy == SG::OWN_ELEMENTS)
-    delete *pos;
+    this->doDelete (*pos);
   else
     this->clearIndex (iterator (pos, this));
   *pos = newElem;
@@ -3518,7 +3576,7 @@ DATAVECTOR::assignElement (typename BaseContainer::iterator pos,
     SG::throwExcNonowningContainer();
 
   testInsert ("assignElement");
-  delete *pos;
+  this->doDelete (*pos);
   value_type ptr = newElem.release();
   *pos = ptr;
   this->moveAux (pos - this->m_pCont.begin(), ptr);
@@ -3539,7 +3597,7 @@ void DATAVECTOR::assignBaseElement (typename BaseContainer::iterator pos,
 {
   testInsert ("assignBaseElement");
   if (this->m_ownPolicy == SG::OWN_ELEMENTS)
-    delete *pos;
+    this->doDelete (*pos);
   else
     this->clearIndex (iterator (pos, this));
   *pos = newElem;
@@ -3624,7 +3682,7 @@ typename DATAVECTOR::PtrVector::iterator
 DATAVECTOR::erase_base(typename PtrVector::iterator position)
 { 
   if (m_ownPolicy == SG::OWN_ELEMENTS && position != m_pCont.end())
-    delete *position;
+    this->doDelete (*position);
   return m_pCont.erase(position);
 }
 
@@ -3649,13 +3707,50 @@ DATAVECTOR::erase_base(typename PtrVector::iterator first,
   if (m_ownPolicy == SG::OWN_ELEMENTS) {
     typename PtrVector::iterator new_end =
       DataVector_detail::remove_duplicates(first, last);
-    typename PtrVector::iterator iter = first;
-    while (iter != new_end) delete *(iter++);
+    this->doDelete (first, new_end);
   }
   return m_pCont.erase(first, last);
 }
 
 
+/**
+ * @brief Delete an element
+ * @param p The element to delete.
+ */
+template <class T>
+inline
+void DATAVECTOR::doDelete (value_type p)
+{
+  if (m_deleter) {
+    m_deleter->doDelete (p);
+  }
+  else {
+    delete p;
+  }
+}
+
+
+/**
+ * @brief Delete a range of elements
+ * @param first Start of range to delete.
+ * @param last End of range to delete.
+ */
+template <class T>
+inline
+void DATAVECTOR::doDelete (typename PtrVector::iterator first,
+                           typename PtrVector::iterator last)
+{
+  if (m_deleter) {
+    m_deleter->doDelete (first, last);
+  }
+  else {
+    for (; first != last; ++first) {
+      delete *first;
+    }
+  }
+}
+
+
 /**
  * @brief Test if we can insert; raise an exception if not.
  * @param op Description of the attempted operation.
diff --git a/Control/AthContainers/CMakeLists.txt b/Control/AthContainers/CMakeLists.txt
index 20179e3c0a41bc056f93bdb54397898a121aa33f..503a7a5e0e0d92d5467058b34d1e4d6091a079cc 100644
--- a/Control/AthContainers/CMakeLists.txt
+++ b/Control/AthContainers/CMakeLists.txt
@@ -7,7 +7,7 @@ atlas_subdir( AthContainers )
 
 # Extra dependencies, based on the environment we are in:
 if( NOT XAOD_STANDALONE )
-   set( extra_libs AthenaKernel SGTools GaudiKernel )
+   set( extra_libs AthenaKernel AthAllocators SGTools GaudiKernel )
    set( extra_sources src/*.cxx )
 endif()
 
diff --git a/Control/AthContainers/test/DataVector_test.icc b/Control/AthContainers/test/DataVector_test.icc
index 1c6b223e41367874ae3cc240bb915f5bd3f5fa78..17acce3150d85b6df9dc5253dde4229ba4eb04fe 100644
--- a/Control/AthContainers/test/DataVector_test.icc
+++ b/Control/AthContainers/test/DataVector_test.icc
@@ -6022,6 +6022,93 @@ void test2_elconversions()
 }
 
 
+template <class DV>
+class TestDeleter
+  : public DV::Deleter
+{
+public:
+  using value_type = typename DV::Deleter::value_type;
+  using PtrVector = typename DV::Deleter::PtrVector;
+
+  TestDeleter (std::vector<int>& the_v) : v(the_v) {}
+
+  virtual void doDelete (value_type p) override
+  {
+    v.push_back (p->x);
+    delete p;
+  }
+  virtual void doDelete (typename PtrVector::iterator first,
+                         typename PtrVector::iterator last) override
+  {
+    for (; first != last; ++first) {
+      v.push_back ((*first)->x);
+      delete *first;
+    }
+  }
+
+  std::vector<int>& v;
+};
+template <class T>
+void test2_deleter1()
+{
+  std::vector<int> v;
+  DataVector<T> dv;
+  dv.clear (std::make_unique<TestDeleter<DataVector<T> > > (v));
+  dv.push_back (new T(1));
+  dv.push_back (new T(2));
+  dv.push_back (new T(3));
+  assert (v.empty());
+  dv.pop_back();
+  assert (v == std::vector<int>{3});
+  v.clear();
+  dv.clear();
+  assert (v == (std::vector<int>{1, 2}));
+}
+
+
+template <class T>
+void test2_deleter2()
+{
+  std::vector<int> v;
+  DataVector<T> dv1;
+  dv1.clear (std::make_unique<TestDeleter<DataVector<T> > > (v));
+  dv1.push_back (new T(1));
+  dv1.push_back (new T(2));
+  dv1.push_back (new T(3));
+
+  DataVector<T> dv2 (std::move (dv1));
+  assert (v.empty());
+  assert (dv1.empty());
+  assert (dv2.size() == 3);
+  dv2.pop_back();
+  assert (v == std::vector<int>{3});
+  v.clear();
+
+  dv1 = std::move (dv2);
+  assert (v.empty());
+  assert (dv1.size() == 2);
+  assert (dv2.empty());
+  dv1.pop_back();
+  assert (v == std::vector<int>{2});
+  v.clear();
+
+  dv1.swap (dv2);
+  assert (v.empty());
+  assert (dv1.empty());
+  assert (dv2.size() == 1);
+  dv2.pop_back();
+  assert (v == std::vector<int>{1});
+}
+
+
+template <class B, class D>
+void test2_deleter()
+{
+  test2_deleter1<B>();
+  test2_deleter1<D>();
+}
+
+
 template <class B, class D>
 void do_test2()
 {
@@ -6084,6 +6171,7 @@ void do_test2()
   test2_move<B,D> ();
   test2_offset<B,D> ();
   test2_elconversions<B,D>();
+  test2_deleter<B,D>();
 }