java构建内存池队列_内存池完整实现代码及一些思考

为了提高效率和有效的监控内存的实时状态,我们采取了内存池的思想来解决效率与对内存实现监控的问题。

网上查找到了一些方案,根据自己的理解实现了应用。

我们什么时候要调用到内存池,

1,当我们频繁的申请释放同样数据大小的内存空间,我们可以用比动态new更有效方式来管理内存时,我们应该用内存池来提高效率。

2,当我们需要知道内存实时的申请状态,以便于对于服务器内存状态做实时预警时,我们可以用内存池的接口,来给内存增加监控。

实现的特点:

1,内存池内存单元大小可以动态定义,实现多级内存池。

2,申请效率很高,单元测试下是普通new/delete的4倍左右,当然具体性能还应机器类别而异。

MemoryPool.h 的实现

//该内存池理论来自于IBM文章,http://www.ibm.com/developerworks/cn/linux/l-cn-ppp/index6.html

//作者冯宏华,徐莹,程远,汪磊享有论文著作权,由2011-06-06 konyel lin根据相关代码和理论进行优化修改。

#include

#include

//内存对齐值,可以根据机器取指长度进行设置

#define MEMPOOL_ALIGNMENT 4

#define USHORT unsigned short

#define ULONG unsigned long

struct MemoryBlock

{

USHORT nSize;

USHORT nFree;

USHORT nFirst;

USHORT nDummyAlign1;

MemoryBlock* pNext;

char aData[1];

static void* operator new(size_t,USHORT nTypes, USHORT nUnitSize){

return ::operator new(sizeof(MemoryBlock) + nTypes * nUnitSize);

}

static void operator delete(void *p, size_t){

::operator delete (p);

}

MemoryBlock (USHORT nTypes = 1, USHORT nUnitSize = 0);

~MemoryBlock() {}

};

class MemoryPool

{

private:

MemoryBlock* pBlock;

USHORT nUnitSize;

USHORT nInitSize;

USHORT nGrowSize;

public:

MemoryPool( USHORT nUnitSize,

USHORT nInitSize = 1024,

USHORT nGrowSize = 256 );

~MemoryPool();

void* Alloc();

void Free( void* p );

};

MemoryPool.cpp 的实现

#include "MemoryPool.h"

MemoryPool::MemoryPool( USHORT _nUnitSize,

USHORT _nInitSize, USHORT _nGrowSize )

{

pBlock = NULL;

nInitSize = _nInitSize;

nGrowSize = _nGrowSize;

if ( _nUnitSize > 4 )

nUnitSize = (_nUnitSize + (MEMPOOL_ALIGNMENT-1)) & ~(MEMPOOL_ALIGNMENT-1);

else if ( _nUnitSize <= 2 )

nUnitSize = 2;

else

nUnitSize = 4;

}

void* MemoryPool::Alloc()

{

MemoryBlock* pMyBlock;

if ( !pBlock ){

//第一次调用初始化内存块

pMyBlock =new(nGrowSize, nUnitSize) MemoryBlock(nGrowSize, nUnitSize);

pBlock = pMyBlock;

return (void*)(pMyBlock->aData);

}

pMyBlock = pBlock;

while (pMyBlock && !pMyBlock->nFree )

pMyBlock = pMyBlock->pNext;

if ( pMyBlock ){

printf("get a mem from block\n");

char* pFree = pMyBlock->aData+(pMyBlock->nFirst*nUnitSize);

//aData记录实际的内存单元标识

pMyBlock->nFirst = *((USHORT*)pFree);

pMyBlock->nFree--;

return (void*)pFree;

}

else{

printf("add a new block\n");

if (!nGrowSize)

return NULL;

pMyBlock = new(nGrowSize, nUnitSize) MemoryBlock(nGrowSize, nUnitSize);

if (!pMyBlock )

return NULL;

pMyBlock->pNext = pBlock;

pBlock = pMyBlock;

return (void*)(pMyBlock->aData);

}

}

void MemoryPool::Free( void* pFree ){

MemoryBlock* pMyBlock = pBlock;

MemoryBlock* preMyBlock;

//确定该待回收分配单元(pFree)落在哪一个内存块的指针范围内,大于起始节点,小于终止节点。

while ( ((ULONG)pMyBlock->aData > (ULONG)pFree) ||

((ULONG)pFree >= ((ULONG)pMyBlock->aData + pMyBlock->nSize))){

//不在内存块范围内,则历遍下一个节点

preMyBlock=pMyBlock;

pMyBlock=pMyBlock->pNext;

}

pMyBlock->nFree++;

*((USHORT*)pFree) = pMyBlock->nFirst;

pMyBlock->nFirst = (USHORT)(((ULONG)pFree-(ULONG)(pBlock->aData)) / nUnitSize);

//判断内存块是否全部为自由状态,是则释放整个内存块

if (pMyBlock->nFree*nUnitSize == pMyBlock->nSize ){

preMyBlock->pNext=pMyBlock->pNext;

delete pMyBlock;

}

}

MemoryBlock::MemoryBlock (USHORT nTypes, USHORT nUnitSize)

: nSize (nTypes * nUnitSize),

nFree (nTypes - 1),

nFirst (1),

pNext (0)

{

char * pData = aData;

for (USHORT i = 1; i < nTypes; i++) {

//将内存块的前2个字节用来存放内存单元的标识

*reinterpret_cast(pData) = i;

pData += nUnitSize;

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/432939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hibernate 第一个体验程序

首先要导入包&#xff0c;将下载的hibernate所有required包导入&#xff0c;将下载的hibernate用来写log的slf4j的api和nopjar包导入&#xff0c;将下载的mysql链接引擎jar包导入。 然后新建java工程。 先告诉hiernate怎么连数据库&#xff1a;在hibernate默认识别目录src根目录…

Django框架里的MVC思想

让我们来研究一个简单的例子&#xff0c;通过该实例&#xff0c;你可以分辨出&#xff0c;通过Web框架来实现的功能与之前的方式有何不同。 下面就是通过使用Django来完成以上功能的例子&#xff1a; 首先&#xff0c;我们分成4个Python的文件&#xff0c;(models.py , views.p…

小米功能机支持java吗_小米竟然卖功能机了!2.8吋/15天超长待机

【手机中国 新闻】众多周知&#xff0c;小米是从智能手机起家的&#xff0c;对于功能机从未涉足。但自从有了强大的小米生态链&#xff0c;制造各种科技产品那都不是事儿了。8月2日上午10点&#xff0c;小米有品众筹频道上线了一款功能手机——QIN多亲AI电话&#xff0c;仅售19…

Linux内核Crash分析

http://blog.chinaunix.net/uid-20788636-id-4377271.html 在工作中经常会遇到一些内核crash的情况&#xff0c;本文就是根据内核出现crash后的打印信息&#xff0c;对其进行了分析&#xff0c;使用的内核版本为&#xff1a;Linux2.6.32。 每一个进程的生命周期内&#xff0c…

java用beaninfo_JavaBeanInfo 和 Spring 之间的关系

Java Beans在这一章章节中笔者将和各位一起探讨关于 Java Beans 相关的内容。本章主要围绕 java.beans 这个包路径下的代码进行一些说明。在 Spring 中我们可以看到 BeanInfoFactory 该接口可以用来获取 Class 对应的 BeanInfo 对象&#xff0c;在 CachedIntrospectionResults …

用键盘实现上下选择

<html> <head> <title>键盘方向键控制表格</title> </head> <body onKeyDown"keyCheck();"> <table width"80" bgcolor"#FFFFFF" height"60" border"1" bordercolor"#FFFFFF&q…

selenium ruby和java_Selenium 2之Ruby版——安装篇

自从知道了Selenium的存在后&#xff0c;就一直都想&#xff0c;若要学习自动化&#xff0c;就要学习像Selenium这种比较有潜力的。Selenium有针对各种语言(java, C#, Python, Ruby, Perl)的版本&#xff0c;在此选择Ruby为学习方向&#xff0c;一来可以借此学习下Ruby&#xf…

基于visual Studio2013解决面试题之0702输出数字

&#xfeff;&#xfeff;&#xfeff;题目解决代码及点评/*输入数字 n&#xff0c;按顺序输出从 1 最大的 n 位 10 进制数。比如输入 3&#xff0c;则输出 1、2、3一直到最大的 3 位数即 999。 */#include <iostream> using namespace std;//在不考虑大数的情况下&#…

冠榕智能灯光控制协议分析(controller-node)

1. 在Z-WAVE PC Controller软件选择已配对的智能开关。 从上图中可以看到&#xff0c;我们的智能开关的node id是11&#xff0c;即0x0B。 2. 向智能开关发送灯光的开闭数据。 CommandClasses选择COMMAND_CLASS_BASIC CommandName选择BASIC_SET Value为00时关闭灯光&#xff0…

java中手动装入新类到类装饰器_关于java:抽象装饰器类中的功能而不是装饰器...

我目前正在阅读《Head First Design Patterns》一书&#xff0c;在"Decorator"一章中有以下示例&#xff1a;在书中&#xff0c;conditionmentDecorator类被描述为一个abstract decorator。下面是代码示例&#xff1a;public abstract class CondimentDecorator exte…

跨浏览器开发工作小结

本篇小结是在2011年时候总结的&#xff0c;当时做一个产品的跨浏览器兼容工作&#xff0c;由于产品开发的时间比较早&#xff0c;最开始只能在IE下面(IE 8、IE 9还有点点问题)使用&#xff0c;做跨浏览器兼容工作的时候&#xff0c;主要是适配IE 6--IE 9、Safari、FireFox、Chr…

冠榕智能灯光控制协议分析(node-controller)

1. 在Z-WAVE PC Controller软件选择已配对的智能开关。 从上图中可以看到&#xff0c;我们的智能开关的node id是11&#xff0c;即0x0B。 2. 按下智能开关&#xff0c;用串口工具可以看到以下信息。 01 0D 00 04 00 0B 07 60 0D 01 01 00 03 FF 6B 01 0D 00 04 00 0B 07 60…

Makefile 的 遗漏分隔符错误信息

Makefile的编写中不可以有空格&#xff0c;留白必须按tab键形成的。 去掉空格&#xff0c;改为tab键后&#xff0c;再执行make命令&#xff0c;就会成功。 学习Makefile可以参考一下链接&#xff1a; http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/ 转载于:htt…

冠榕智能灯光控制协议分析(controller-node) 2

z-wave第一篇&#xff0c;我们用COMMAND_CLASS_BASIC - BASIC_SET控制智能开关。但是智能开关上有两个执行器&#xff0c;我们只能控制其中一路&#xff0c;那么我们如何控制另一路的开关的。在z-wave第二篇&#xff0c;我们分析了智能开关两个按键发送的消息&#xff0c;发现&…

java修改pdf内容流_java – 在PDFBox中,如何更改PDRectangle对象的原点(0,0)?

你可以稍微改变坐标系,但最有可能的事情不会变得更加优雅.首先……首先让我们澄清一些误解&#xff1a;你假设In PDFBox, PDRectangle objects’ default origin (0,0) seems to be the lower-left corner of a page.对于所有情况都不是这样,仅仅是经常.包含显示的页面区域(在纸…

基于visual Studio2013解决面试题之0902内存拷贝

&#xfeff;&#xfeff;&#xfeff;题目解决代码及点评/*用 C 语言实现函数 void * memmove(void *dest,const void *src,size_t n)memmove 函数的功能是拷贝 src 所指的内存内容前 n 个字节到 dest 所指的地址上。 简单循环拷贝即可&#xff0c;但是这道题&#xff0c;要深…

冠榕智能灯光控制协议分析(controller init)

上面几篇已经详细介绍了z-wave协议的分析方法&#xff0c;这一章&#xff0c;我们分析z-wave pc controller初始化时的通信信息。我们只将关键信息列出&#xff0c;然后直接将分析出来的串口数据列出。 1. 得到z-wave版本 01 03 00 15 E9 06 01 10 01 15 5A 2D 57 61 76 65…

jmeter找不到java_Windows下Jmeter安装出现Not able to find Java executable or version问题解决方案...

最近在做一个开放接口平台性能测试 , 指标是最少达到1000/s的并发 , 接口鉴权 百万级的表 在1s内完成..在众多压测工具中 ,,选择了Apache的jmeter ,于官网下载了最新版本http://jmeter.apache.org/download_jmeter.cgi (jmeter下载地址)由于jmeter运行是基于java的,所以需要…

java 第三方库

总结一下常用的java第三方库&#xff0c;方便查询和使用&#xff0c;欢迎补充。 1、核心库 Apache Commons Lang&#xff1a;来自Apache的核心库&#xff0c;为java.lang API补充了许多常用的工具类&#xff0c;如字符串操作、对象的创建等。 Google Guava&#xff1a;来自谷歌…

ZDB5304烧写方法

1&#xff0e; 跳线和5304的位置如下图 2. 打开z-wave programmer软件&#xff0c;设置如下图&#xff0c;注意烧写接口为uart&#xff0c;烧写的时候会提示的。选yes是uart&#xff0c;选no是spi。 烧写过程中会提示按下reset或释放reset按键。照做即可。 烧完后&#xff0c…