diff --git a/src/alloc.rs b/src/alloc.rs
index 0be634f0818de6a64e714c5229f1a4a41ec3c931..39312f2a571fa30614561334595dc2dbe7afd315 100644
--- a/src/alloc.rs
+++ b/src/alloc.rs
@@ -1,9 +1,5 @@
 use std::{mem, ptr};
-use std::ops::DerefMut;
 use std::sync::atomic::{AtomicUsize, Ordering};
-use std::usize;
-
-const MAX_ALLOC_SIZE: usize = usize::MAX;
 
 /// Allocates memory to be used by Bufs or Bytes. Allows allocating memory
 /// using alternate stratgies than the default Rust heap allocator. Also does
@@ -114,7 +110,7 @@ pub struct Mem {
 }
 
 impl Mem {
-    fn new(len: usize, allocator: *const Allocator) -> Mem {
+    pub fn new(len: usize, allocator: *const Allocator) -> Mem {
         Mem {
             allocator: allocator,
             refs: AtomicUsize::new(1),
@@ -122,52 +118,3 @@ impl Mem {
         }
     }
 }
-
-pub static HEAP: Heap = Heap;
-
-pub struct Heap;
-
-impl Heap {
-    pub fn allocate(&self, len: usize) -> MemRef {
-        // Make sure that the allocation is within the permitted range
-        if len > MAX_ALLOC_SIZE {
-            return MemRef::none();
-        }
-
-        let alloc_len = len +
-            mem::size_of::<Mem>() +
-            mem::size_of::<Vec<u8>>();
-
-        unsafe {
-            let mut vec: Vec<u8> = Vec::with_capacity(alloc_len);
-            vec.set_len(alloc_len);
-
-            let ptr = vec.deref_mut().as_mut_ptr();
-
-            ptr::write(ptr as *mut Vec<u8>, vec);
-
-            let ptr = ptr.offset(mem::size_of::<Vec<u8>>() as isize);
-            ptr::write(ptr as *mut Mem, Mem::new(len, mem::transmute(self as &Allocator)));
-
-            // Return the info
-            MemRef::new(ptr as *mut Mem)
-        }
-    }
-
-    pub fn deallocate(&self, mem: *mut Mem) {
-        unsafe {
-            let ptr = mem as *mut u8;
-            let _ = ptr::read(ptr.offset(-(mem::size_of::<Vec<u8>>() as isize)) as *const Vec<u8>);
-        }
-    }
-}
-
-impl Allocator for Heap {
-    fn allocate(&self, len: usize) -> MemRef {
-        Heap::allocate(self, len)
-    }
-
-    fn deallocate(&self, mem: *mut Mem) {
-        Heap::deallocate(self, mem)
-    }
-}
diff --git a/src/byte_buf.rs b/src/byte_buf.rs
index deb2a8888def62416d40da86dcda74aff68d2513..cf8fc4d47aa46d613eb43853107bacafb36da6ab 100644
--- a/src/byte_buf.rs
+++ b/src/byte_buf.rs
@@ -1,4 +1,4 @@
-use {alloc, Bytes, SeqByteStr, MAX_CAPACITY};
+use {alloc, heap, Bytes, SeqByteStr, MAX_CAPACITY};
 use traits::{Buf, MutBuf, MutBufExt, ByteStr};
 use std::{cmp, ptr};
 
@@ -59,7 +59,7 @@ impl ByteBuf {
         capacity = capacity.next_power_of_two();
 
         // Allocate the memory
-        let mem = alloc::HEAP.allocate(capacity as usize);
+        let mem = heap::allocate(capacity as usize);
 
         // If the allocation failed, return a blank buf
         if mem.is_none() {
diff --git a/src/heap.rs b/src/heap.rs
new file mode 100644
index 0000000000000000000000000000000000000000..d78ef6c8e7b519715ba5ac5407fb3cbb73495701
--- /dev/null
+++ b/src/heap.rs
@@ -0,0 +1,58 @@
+use alloc::{Allocator, Mem, MemRef};
+use std::{mem, ptr, usize};
+use std::ops::DerefMut;
+
+const MAX_ALLOC_SIZE: usize = usize::MAX;
+
+pub fn allocate(len: usize) -> MemRef {
+    HEAP.allocate(len)
+}
+
+pub struct Heap;
+
+pub static HEAP: Heap = Heap;
+
+impl Heap {
+    pub fn allocate(&self, len: usize) -> MemRef {
+        // Make sure that the allocation is within the permitted range
+        if len > MAX_ALLOC_SIZE {
+            return MemRef::none();
+        }
+
+        let alloc_len = len +
+            mem::size_of::<Mem>() +
+            mem::size_of::<Vec<u8>>();
+
+        unsafe {
+            let mut vec: Vec<u8> = Vec::with_capacity(alloc_len);
+            vec.set_len(alloc_len);
+
+            let ptr = vec.deref_mut().as_mut_ptr();
+
+            ptr::write(ptr as *mut Vec<u8>, vec);
+
+            let ptr = ptr.offset(mem::size_of::<Vec<u8>>() as isize);
+            ptr::write(ptr as *mut Mem, Mem::new(len, mem::transmute(self as &Allocator)));
+
+            // Return the info
+            MemRef::new(ptr as *mut Mem)
+        }
+    }
+
+    pub fn deallocate(&self, mem: *mut Mem) {
+        unsafe {
+            let ptr = mem as *mut u8;
+            let _ = ptr::read(ptr.offset(-(mem::size_of::<Vec<u8>>() as isize)) as *const Vec<u8>);
+        }
+    }
+}
+
+impl Allocator for Heap {
+    fn allocate(&self, len: usize) -> MemRef {
+        Heap::allocate(self, len)
+    }
+
+    fn deallocate(&self, mem: *mut Mem) {
+        Heap::deallocate(self, mem)
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 1d66fd65915869ca5551d6753d7def7e0fa68148..c4f66bb02a37cf72fb7052860f5e58d55dc0f8aa 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,6 +15,7 @@ mod alloc;
 mod byte_buf;
 mod byte_str;
 mod bytes;
+mod heap;
 mod ring;
 mod rope;
 mod slice;
diff --git a/src/ring.rs b/src/ring.rs
index 20bab4ac13c59f93589168f997793ac3b14edcfd..e322e4d5a880a4c2a2e654cd0a626c19268fdce9 100644
--- a/src/ring.rs
+++ b/src/ring.rs
@@ -1,4 +1,4 @@
-use {alloc, Buf, MutBuf};
+use {alloc, heap, Buf, MutBuf};
 use std::{cmp, fmt, io, ptr};
 
 /// Buf backed by a continous chunk of memory. Maintains a read cursor and a
@@ -27,7 +27,7 @@ impl RingBuf {
         // Round to the next power of 2 for better alignment
         capacity = capacity.next_power_of_two();
 
-        let mem = alloc::HEAP.allocate(capacity as usize);
+        let mem = heap::allocate(capacity as usize);
 
         RingBuf {
             ptr: mem,