基于内存消耗的自动缓存驱逐

huangapple go评论86阅读模式
英文:

Automatic cache eviction based on memory consumption

问题

我想实现一个高效的LRU缓存,它可以根据可用内存自动淘汰项目。

目前我只能想到两种方法:

  • 使用gosigar进行轮询。
  • 或者设置一个固定的最大值,并定期使用runtime.ReadMemStats进行检查。

还有其他的方法吗?memcached是如何实现的?

英文:

I want to implement an efficient LRU cache that automatically evicts items based on free memory.

Right now only 2 things come to mind:

  • Poll with gosigar
  • or set a fixed maximum and periodically check runtime.ReadMemStats.

Are there any other ways? How does memcached do it?

答案1

得分: 1

我每秒轮询系统内存统计信息来实现它。

请参阅:https://github.com/eaigner/last

在Linux上读取内存统计信息:

import (
	"syscall"
)

func ReadSysMemStats(s *MemStats) error {
	if s == nil {
		return nil
	}
	var info syscall.Sysinfo_t
	err := syscall.Sysinfo(&info)
	if err != nil {
		return err
	}

	s.Total = info.Totalram
	s.Free = info.Freeram
	s.Used = s.Total - s.Free

	return nil
}

在Darwin/OSX上:

/*
#include <mach/mach.h>
#include <mach/mach_host.h>
*/
import "C"

import (
	"fmt"
	"unsafe"
)

func readSysMemStats(s *SysMemStats) error {
	if s == nil {
		return nil
	}
	var vm_pagesize C.vm_size_t
	var vm_stat C.vm_statistics_data_t
	var count C.mach_msg_type_number_t = C.HOST_VM_INFO_COUNT

	host_port := C.host_t(C.mach_host_self())

	C.host_page_size(host_port, &vm_pagesize)

	status := C.host_statistics(
		host_port,
		C.HOST_VM_INFO,
		C.host_info_t(unsafe.Pointer(&vm_stat)),
		&count)

	if status != C.KERN_SUCCESS {
		return fmt.Errorf("could not get vm statistics: %d", status)
	}

	// Stats in bytes
	free := uint64(vm_stat.free_count)
	active := uint64(vm_stat.active_count)
	inactive := uint64(vm_stat.inactive_count)
	wired := uint64(vm_stat.wire_count)
	pagesize := uint64(vm_pagesize)

	s.Used = (active + inactive + wired) * pagesize
	s.Free = free * pagesize
	s.Total = s.Used + s.Free

	return nil
}
英文:

I implemented it polling the system memory statistics every 1 second.

See: https://github.com/eaigner/last

Read memory stats on Linux:

import (
	&quot;syscall&quot;
)

func ReadSysMemStats(s *MemStats) error {
	if s == nil {
		return nil
	}
	var info syscall.Sysinfo_t
	err := syscall.Sysinfo(&amp;info)
	if err != nil {
		return err
	}

	s.Total = info.Totalram
	s.Free = info.Freeram
	s.Used = s.Total - s.Free

	return nil
}

And on Darwin/OSX

/*
#include &lt;mach/mach.h&gt;
#include &lt;mach/mach_host.h&gt;
*/
import &quot;C&quot;

import (
	&quot;fmt&quot;
	&quot;unsafe&quot;
)

func readSysMemStats(s *SysMemStats) error {
	if s == nil {
		return nil
	}
	var vm_pagesize C.vm_size_t
	var vm_stat C.vm_statistics_data_t
	var count C.mach_msg_type_number_t = C.HOST_VM_INFO_COUNT

	host_port := C.host_t(C.mach_host_self())

	C.host_page_size(host_port, &amp;vm_pagesize)

	status := C.host_statistics(
		host_port,
		C.HOST_VM_INFO,
		C.host_info_t(unsafe.Pointer(&amp;vm_stat)),
		&amp;count)

	if status != C.KERN_SUCCESS {
		return fmt.Errorf(&quot;could not get vm statistics: %d&quot;, status)
	}

	// Stats in bytes
	free := uint64(vm_stat.free_count)
	active := uint64(vm_stat.active_count)
	inactive := uint64(vm_stat.inactive_count)
	wired := uint64(vm_stat.wire_count)
	pagesize := uint64(vm_pagesize)

	s.Used = (active + inactive + wired) * pagesize
	s.Free = free * pagesize
	s.Total = s.Used + s.Free

	return nil
}

huangapple
  • 本文由 发表于 2013年11月15日 19:48:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/20000404.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定