diff --git a/src/bytes.rs b/src/bytes.rs
index 4fd958b045b8abf90e3e56470c580c3ce9d400ca..f65f7722bf6e8383cb4e6eb9512a08002a1a9840 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -1029,55 +1029,51 @@ impl BytesMut {
     /// More than `additional` bytes may be reserved in order to avoid frequent
     /// reallocations. A call to `reserve` may result in an allocation.
     ///
+    /// Before allocating new buffer space, the function will attempt to reclaim
+    /// space in the existing buffer. If the current handle references a small
+    /// view in the original buffer and all other handles have been dropped,
+    /// and the requested capacity is less than or equal to the existing
+    /// buffer's capacity, then the current view will be copied to the front of
+    /// the buffer and the handle will take ownership of the full buffer.
+    ///
     /// # Examples
     ///
+    /// In the following example, a new buffer is allocated.
+    ///
     /// ```
     /// use bytes::BytesMut;
     ///
-    /// let mut b = BytesMut::from(&b"hello"[..]);
-    /// b.reserve(64);
-    /// assert!(b.capacity() >= 69);
+    /// let mut buf = BytesMut::from(&b"hello"[..]);
+    /// buf.reserve(64);
+    /// assert!(buf.capacity() >= 69);
     /// ```
     ///
-    /// # Panics
-    ///
-    /// Panics if the new capacity overflows usize.
-    pub fn reserve(&mut self, additional: usize) {
-        self.inner.reserve(additional)
-    }
-
-    /// Attempts to reclaim ownership of the full buffer.
+    /// In the following example, the existing buffer is reclaimed.
     ///
-    /// Returns `true` if the reclaim is successful.
+    /// ```
+    /// use bytes::{BytesMut, BufMut};
     ///
-    /// If the `BytesMut` handle is the only outstanding handle pointing to the
-    /// memory slice, the handle's view will be set to the full memory slice,
-    /// enabling reusing buffer space without allocating.
+    /// let mut buf = BytesMut::with_capacity(128);
+    /// buf.put(&[0; 64][..]);
     ///
-    /// Any data in the `BytesMut` handle will be copied to the start of the
-    /// memory region.
+    /// let ptr = buf.as_ptr();
+    /// let other = buf.drain();
     ///
-    /// ```rust
-    /// use bytes::BytesMut;
+    /// assert!(buf.is_empty());
+    /// assert_eq!(buf.capacity(), 64);
     ///
-    /// let mut bytes = BytesMut::from(
-    ///     "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+    /// drop(other);
+    /// buf.reserve(128);
     ///
-    /// // Create a new handle to the shared memory region
-    /// let a = bytes.drain_to(5);
+    /// assert_eq!(buf.capacity(), 128);
+    /// assert_eq!(buf.as_ptr(), ptr);
+    /// ```
     ///
-    /// // Attempting to reclaim here will fail due to `a` still being in
-    /// // existence.
-    /// assert!(!bytes.try_reclaim());
-    /// assert_eq!(bytes.capacity(), 51);
+    /// # Panics
     ///
-    /// // Dropping the handle will allow reclaim to succeed.
-    /// drop(a);
-    /// assert!(bytes.try_reclaim());
-    /// assert_eq!(bytes.capacity(), 56);
-    /// ```
-    pub fn try_reclaim(&mut self) -> bool {
-        self.inner.try_reclaim()
+    /// Panics if the new capacity overflows usize.
+    pub fn reserve(&mut self, additional: usize) {
+        self.inner.reserve(additional)
     }
 }
 
@@ -1672,7 +1668,36 @@ impl Inner {
         // allocating a new vector with the requested capacity.
         //
         // Compute the new capacity
-        let new_cap = len + additional;
+        let mut new_cap = len + additional;
+
+        unsafe {
+            // First, try to reclaim the buffer. This is possible if the current
+            // handle is the only outstanding handle pointing to the buffer.
+            if (*arc).is_unique() {
+                // This is the only handle to the buffer. It can be reclaimed.
+                // However, before doing the work of copying data, check to make
+                // sure that the vector has enough capacity.
+                let v = &mut (*arc).vec;
+
+                if v.capacity() >= new_cap {
+                    // The capacity is sufficient, reclaim the buffer
+                    let ptr = v.as_mut_ptr();
+
+                    ptr::copy(self.ptr, ptr, len);
+
+                    self.ptr = ptr;
+                    self.cap = v.capacity();
+
+                    return;
+                }
+
+                // The vector capacity is not sufficient. The reserve request is
+                // asking for more than the initial buffer capacity. Allocate more
+                // than requested if `new_cap` is not much bigger than the current
+                // capacity.
+                new_cap = cmp::max(len << 1, new_cap);
+            }
+        }
 
         // Create a new vector to store the data
         let mut v = Vec::with_capacity(new_cap);
@@ -1694,53 +1719,6 @@ impl Inner {
         mem::forget(v);
     }
 
-    /// This must take `&mut self` in order to be able to copy memory in the
-    /// inline case.
-    #[inline]
-    fn try_reclaim(&mut self) -> bool {
-        // Always check `inline` first, because if the handle is using inline
-        // data storage, all of the `Inner` struct fields will be gibberish.
-        if self.is_inline() {
-            // No further work to do. Inlined buffers are always "reclaimed".
-            return true;
-        }
-
-        // `Relaxed` is Ok here (and really, no synchronization is necessary)
-        // due to having a `&mut self` pointer. The `&mut self` pointer ensures
-        // that there is no concurrent access on `self`.
-        let arc = self.arc.load(Relaxed);
-
-        if arc.is_null() {
-            // Vec storage is already reclaimed
-            return true;
-        }
-
-        debug_assert!(!self.is_static());
-
-        unsafe {
-            if !(*arc).is_unique() {
-                // Cannot reclaim buffers that are shared.
-                return false;
-            }
-
-            // This is the only handle to the buffer. It can be reclaimed.
-
-            // Get to the shared vector
-            let v = &mut (*arc).vec;
-
-            let len = v.len();
-            let ptr = v.as_mut_ptr();
-
-            ptr::copy(self.ptr, ptr, len);
-
-            self.ptr = ptr;
-            self.len = len;
-            self.cap = v.capacity();
-
-            true
-        }
-    }
-
     /// Returns true if the buffer is stored inline
     #[inline]
     fn is_inline(&self) -> bool {
diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs
index 50ef9e90f2ef372304e8fd882608b03151ac25e6..89bddafcfeacd1d2929bef75a808b421507bf7b6 100644
--- a/tests/test_bytes.rs
+++ b/tests/test_bytes.rs
@@ -241,52 +241,6 @@ fn reserve() {
     drop(a);
 }
 
-#[test]
-fn try_reclaim_1() {
-    // Inline w/ start at zero
-    let mut bytes = BytesMut::from(&SHORT[..]);
-    assert!(bytes.try_reclaim());
-    assert_eq!(bytes.capacity(), inline_cap());
-    assert_eq!(bytes, SHORT);
-
-    // Inline w/ start not at zero
-    let mut bytes = BytesMut::from(&SHORT[..]);
-    let _ = bytes.drain_to(2);
-    assert_eq!(bytes.capacity(), inline_cap());
-    assert!(bytes.try_reclaim());
-    assert_eq!(bytes.capacity(), inline_cap());
-    assert_eq!(bytes, &SHORT[2..]);
-
-    // Arc
-    let mut bytes = BytesMut::from(&LONG[..]);
-    let a = bytes.drain_to(2);
-    assert!(!bytes.try_reclaim());
-    assert_eq!(bytes.capacity(), LONG.len() - 2);
-
-    drop(a);
-    assert!(bytes.try_reclaim());
-    assert_eq!(bytes.capacity(), LONG.len());
-}
-
-#[test]
-fn try_reclaim_2() {
-    let mut bytes = BytesMut::from(
-        "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
-
-    // Create a new handle to the shared memory region
-    let a = bytes.drain_to(5);
-
-    // Attempting to reclaim here will fail due to `a` still being in
-    // existence.
-    assert!(!bytes.try_reclaim());
-    assert_eq!(bytes.capacity(), 51);
-
-    // Dropping the handle will allow reclaim to succeed.
-    drop(a);
-    assert!(bytes.try_reclaim());
-    assert_eq!(bytes.capacity(), 56);
-}
-
 #[test]
 fn inline_storage() {
     let mut bytes = BytesMut::with_capacity(inline_cap());