diff --git a/collector/meminfo.go b/collector/meminfo.go
new file mode 100644
index 00000000..4322470c
--- /dev/null
+++ b/collector/meminfo.go
@@ -0,0 +1,59 @@
+// Copyright 2015 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// +build !nomeminfo
+
+package collector
+
+import (
+	"fmt"
+
+	"github.com/prometheus/client_golang/prometheus"
+	"github.com/prometheus/common/log"
+)
+
+const (
+	memInfoSubsystem = "memory"
+)
+
+type meminfoCollector struct{}
+
+func init() {
+	Factories["meminfo"] = NewMeminfoCollector
+}
+
+// NewMeminfoCollector returns a new Collector exposing memory stats.
+func NewMeminfoCollector() (Collector, error) {
+	return &meminfoCollector{}, nil
+}
+
+// Update calls (*meminfoCollector).getMemInfo to get the platform specific
+// memory metrics.
+func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
+	memInfo, err := c.getMemInfo()
+	if err != nil {
+		return fmt.Errorf("couldn't get meminfo: %s", err)
+	}
+	log.Debugf("Set node_mem: %#v", memInfo)
+	for k, v := range memInfo {
+		ch <- prometheus.MustNewConstMetric(
+			prometheus.NewDesc(
+				prometheus.BuildFQName(Namespace, memInfoSubsystem, k),
+				fmt.Sprintf("Memory information field %s.", k),
+				nil, nil,
+			),
+			prometheus.GaugeValue, v,
+		)
+	}
+	return nil
+}
diff --git a/collector/meminfo_bsd.go b/collector/meminfo_bsd.go
index bcdc3879..be17d7a9 100644
--- a/collector/meminfo_bsd.go
+++ b/collector/meminfo_bsd.go
@@ -11,7 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// +build freebsd darwin,amd64 dragonfly
+// +build freebsd dragonfly
 // +build !nomeminfo
 
 package collector
@@ -19,52 +19,33 @@ package collector
 import (
 	"fmt"
 
-	"github.com/prometheus/client_golang/prometheus"
 	"golang.org/x/sys/unix"
 )
 
-const (
-	memInfoSubsystem = "memory"
-)
-
-type meminfoCollector struct{}
-
-func init() {
-	Factories["meminfo"] = NewMeminfoCollector
-}
-
-// Takes a prometheus registry and returns a new Collector exposing
-// Memory stats.
-func NewMeminfoCollector() (Collector, error) {
-	return &meminfoCollector{}, nil
-}
-
-func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
-	pages := make(map[string]uint32)
+func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
+	info := make(map[string]float64)
 
 	size, err := unix.SysctlUint32("vm.stats.vm.v_page_size")
 	if err != nil {
-		return fmt.Errorf("sysctl(vm.stats.vm.v_page_size) failed: %s", err)
+		return nil, fmt.Errorf("sysctl(vm.stats.vm.v_page_size) failed: %s", err)
 	}
-	pages["active"], _ = unix.SysctlUint32("vm.stats.vm.v_active_count")
-	pages["inactive"], _ = unix.SysctlUint32("vm.stats.vm.v_inactive_count")
-	pages["wire"], _ = unix.SysctlUint32("vm.stats.vm.v_wire_count")
-	pages["cache"], _ = unix.SysctlUint32("vm.stats.vm.v_cache_count")
-	pages["free"], _ = unix.SysctlUint32("vm.stats.vm.v_free_count")
-	pages["swappgsin"], _ = unix.SysctlUint32("vm.stats.vm.v_swappgsin")
-	pages["swappgsout"], _ = unix.SysctlUint32("vm.stats.vm.v_swappgsout")
-	pages["total"], _ = unix.SysctlUint32("vm.stats.vm.v_page_count")
 
-	for k, v := range pages {
-		ch <- prometheus.MustNewConstMetric(
-			prometheus.NewDesc(
-				prometheus.BuildFQName(Namespace, memInfoSubsystem, k),
-				k+" from sysctl()",
-				nil, nil,
-			),
-			// Convert metrics to kB (same as Linux meminfo).
-			prometheus.UntypedValue, float64(v)*float64(size),
-		)
+	for key, v := range map[string]string{
+		"active":     "vm.stats.vm.v_active_count",
+		"inactive":   "vm.stats.vm.v_inactive_count",
+		"wire":       "vm.stats.vm.v_wire_count",
+		"cache":      "vm.stats.vm.v_cache_count",
+		"free":       "vm.stats.vm.v_free_count",
+		"swappgsin":  "vm.stats.vm.v_swappgsin",
+		"swappgsout": "vm.stats.vm.v_swappgsout",
+		"total":      "vm.stats.vm.v_page_count",
+	} {
+		value, err := unix.SysctlUint32(v)
+		if err != nil {
+			return nil, err
+		}
+		// Convert metrics to kB (same as Linux meminfo).
+		info[key] = float64(value) * float64(size)
 	}
-	return err
+	return info, nil
 }
diff --git a/collector/meminfo_darwin.go b/collector/meminfo_darwin.go
new file mode 100644
index 00000000..0aa35ce0
--- /dev/null
+++ b/collector/meminfo_darwin.go
@@ -0,0 +1,59 @@
+// Copyright 2015 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// +build !nomeminfo
+
+package collector
+
+// #include <mach/mach_host.h>
+import "C"
+
+import (
+	"encoding/binary"
+	"fmt"
+	"syscall"
+	"unsafe"
+
+	"golang.org/x/sys/unix"
+)
+
+func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
+	infoCount := C.mach_msg_type_number_t(C.HOST_VM_INFO_COUNT)
+	vmstat := C.vm_statistics_data_t{}
+	ret := C.host_statistics(
+		C.host_t(C.mach_host_self()),
+		C.HOST_VM_INFO,
+		C.host_info_t(unsafe.Pointer(&vmstat)),
+		&infoCount,
+	)
+	if ret != C.KERN_SUCCESS {
+		return nil, fmt.Errorf("Couldn't get memory statistics, host_statistics returned %d", ret)
+	}
+	totalb, err := unix.Sysctl("hw.memsize")
+	if err != nil {
+		return nil, err
+	}
+	// Syscall removes terminating NUL which we need to cast to uint64
+	total := binary.LittleEndian.Uint64([]byte(totalb + "\x00"))
+
+	ps := C.natural_t(syscall.Getpagesize())
+	return map[string]float64{
+		"active_bytes_total":      float64(ps * vmstat.active_count),
+		"inactive_bytes_total":    float64(ps * vmstat.inactive_count),
+		"wired_bytes_total":       float64(ps * vmstat.wire_count),
+		"free_bytes_total":        float64(ps * vmstat.free_count),
+		"swapped_in_pages_total":  float64(ps * vmstat.pageins),
+		"swapped_out_pages_total": float64(ps * vmstat.pageouts),
+		"bytes_total":             float64(total),
+	}, nil
+}
diff --git a/collector/meminfo_linux.go b/collector/meminfo_linux.go
index d1ebe26c..1a8556fd 100644
--- a/collector/meminfo_linux.go
+++ b/collector/meminfo_linux.go
@@ -23,47 +23,9 @@ import (
 	"regexp"
 	"strconv"
 	"strings"
-
-	"github.com/prometheus/client_golang/prometheus"
-	"github.com/prometheus/common/log"
 )
 
-const (
-	memInfoSubsystem = "memory"
-)
-
-type meminfoCollector struct{}
-
-func init() {
-	Factories["meminfo"] = NewMeminfoCollector
-}
-
-// Takes a prometheus registry and returns a new Collector exposing
-// memory stats.
-func NewMeminfoCollector() (Collector, error) {
-	return &meminfoCollector{}, nil
-}
-
-func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
-	memInfo, err := getMemInfo()
-	if err != nil {
-		return fmt.Errorf("couldn't get meminfo: %s", err)
-	}
-	log.Debugf("Set node_mem: %#v", memInfo)
-	for k, v := range memInfo {
-		ch <- prometheus.MustNewConstMetric(
-			prometheus.NewDesc(
-				prometheus.BuildFQName(Namespace, memInfoSubsystem, k),
-				fmt.Sprintf("Memory information field %s.", k),
-				nil, nil,
-			),
-			prometheus.GaugeValue, v,
-		)
-	}
-	return nil
-}
-
-func getMemInfo() (map[string]float64, error) {
+func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
 	file, err := os.Open(procFilePath("meminfo"))
 	if err != nil {
 		return nil, err