当前位置: 首页 > 编程日记 > 正文

跟着石头哥哥学cocos2d-x(三)---2dx引擎中的内存管理模型

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

2dx引擎中的对象内存管理模型,很简单就是一个对象池+引用计数,本着学好2dx的好奇心,先这里开走吧,紧接上面两节,首先我们看一个编码场景代码:

hello word :


#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"class HelloWorld : public cocos2d::CCLayer
{
public:// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphonevirtual bool init();  // there's no 'id' in cpp, so we recommend returning the class instance pointerstatic cocos2d::CCScene* scene();// a selector callbackvoid menuCloseCallback(CCObject* pSender);// implement the "static node()" method manuallyCREATE_FUNC(HelloWorld);
};#endif // __HELLOWORLD_SCENE_H__



#include "HelloWorldScene.h"USING_NS_CC;CCScene* HelloWorld::scene()
{// 'scene' is an autorelease objectCCScene *scene = CCScene::create();// 'layer' is an autorelease objectHelloWorld *layer = HelloWorld::create();// add layer as a child to scenescene->addChild(layer);// return the scenereturn scene;
}// on "init" you need to initialize your instance
bool HelloWorld::init()
{//// 1. super init firstif ( !CCLayer::init() ){return false;}CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();/// 2. add a menu item with "X" image, which is clicked to quit the program//    you may modify it.// add a "close" icon to exit the progress. it's an autorelease objectCCMenuItemImage *pCloseItem = CCMenuItemImage::create("CloseNormal.png","CloseSelected.png",this,menu_selector(HelloWorld::menuCloseCallback));pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,origin.y + pCloseItem->getContentSize().height/2));// create menu, it's an autorelease objectCCMenu* pMenu = CCMenu::create(pCloseItem, NULL);pMenu->setPosition(CCPointZero);this->addChild(pMenu, 1);/// 3. add your codes below...// add a label shows "Hello World"// create and initialize a labelCCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);// position the label on the center of the screenpLabel->setPosition(ccp(origin.x + visibleSize.width/2,origin.y + visibleSize.height - pLabel->getContentSize().height));// add the label as a child to this layerthis->addChild(pLabel, 1);// add "HelloWorld" splash screen"CCSprite* pSprite = CCSprite::create("HelloWorld.png");// position the sprite on the center of the screenpSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));// add the sprite as a child to this layerthis->addChild(pSprite, 0);return true;
}//close application
void HelloWorld::menuCloseCallback(CCObject* pSender)
{CCDirector::sharedDirector()->end();#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)exit(0);
#endif
}




代码片段中有一个 CREATE_FUNC(HelloWorld);   HelloWorld *layer = HelloWorld::create();

跟进看到,其实创建这个层的方法就是定义的CREATE_FUNC(xx);继续追踪,可以看到,他创建这个层,同时会调用初始化inti()方法--准备layer基础数据,也就是java上见的多的多态,这不是重点,他调用了,autorelease(),也就是我们对象内存模型中的自动管理方法,这里我先直接总结下,对象在创建的过程中,创建之后,调用autorelease(),就会被添加到对象池中自动维护计数,当计数未0(在每一帧结束后),或者在析构中调用销毁,那么就将会冲对象池中移除;在看一个例子:CCArray *test=CCArray::create();test->retain();

这样才是才会创建成功(额排除其他异常);当我们创建这个对象的时候,create()在返回这个对象的同时会将对象自动autorelease();所以你必须还得引用计数+1;为什么?

因为autorelease()将对象添加到对象池中,会自动release(),引用计算--1;默认引用计数为1,当对象创建的时候,所以知道为什么会创建失败了吧 如果标记对象被引用;当然你自己创建的对象就要这样处理,如果是2dx的捏?那就直接穿件创建autorelease(),内存对象池会自动处理的;

接下来直接看内存模型+引用计数,内存对象缓存是用的CCArray;具体看下面代码片段,该有的注解都有了:

先是2dx中:object,java中所有对象的根接点,这里你可以这样“理解”:

/****************************************************************************
Copyright (c) 2010 cocos2d-x.orghttp://www.cocos2d-x.orgPermission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/#ifndef __CCOBJECT_H__
#define __CCOBJECT_H__#include "CCDataVisitor.h"#ifdef EMSCRIPTEN
#include <GLES2/gl2.h>
#endif // EMSCRIPTENNS_CC_BEGIN/*** @addtogroup base_nodes* @{*/class CCZone;
class CCObject;
class CCNode;
class CCEvent;class CC_DLL CCCopying
{
public:virtual CCObject* copyWithZone(CCZone* pZone);
};
//对象继承CCobject 都可以引用自动释放池对象(引用计数+释放池管理类)
//根据开发的内容来划分池对象,譬如一个场景创建一个自动释放池,游戏中场景切换时,释放缓冲区最好时间
//引擎基类
class CC_DLL CCObject : public CCCopying
{
public:// 对象IDunsigned int        m_uID;// Lua reference idint                 m_nLuaID;
protected:// 计数对象unsigned int        m_uReference;// count of autorelease 计数自动释放对象unsigned int        m_uAutoReleaseCount;
public:CCObject(void);virtual ~CCObject(void);void release(void);void retain(void);CCObject* autorelease(void);CCObject* copy(void);bool isSingleReference(void) const;unsigned int retainCount(void) const;virtual bool isEqual(const CCObject* pObject);virtual void acceptVisitor(CCDataVisitor &visitor);virtual void update(float dt) {CC_UNUSED_PARAM(dt);};//自动释放池friend class CCAutoreleasePool;
};typedef void (CCObject::*SEL_SCHEDULE)(float);
typedef void (CCObject::*SEL_CallFunc)();
typedef void (CCObject::*SEL_CallFuncN)(CCNode*);
typedef void (CCObject::*SEL_CallFuncND)(CCNode*, void*);
typedef void (CCObject::*SEL_CallFuncO)(CCObject*);
typedef void (CCObject::*SEL_MenuHandler)(CCObject*);
//if button ,do CCEvent *evnet  参数
typedef void (CCObject::*SEL_EventHandler)(CCEvent*);
typedef int (CCObject::*SEL_Compare)(CCObject*);
//各种回调函数接口!!!
#define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR)
#define callfunc_selector(_SELECTOR) (SEL_CallFunc)(&_SELECTOR)
#define callfuncN_selector(_SELECTOR) (SEL_CallFuncN)(&_SELECTOR)
#define callfuncND_selector(_SELECTOR) (SEL_CallFuncND)(&_SELECTOR)
#define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR)
#define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR)
#define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR)
#define compare_selector(_SELECTOR) (SEL_Compare)(&_SELECTOR)// end of base_nodes group
/// @}NS_CC_END#endif // __CCOBJECT_H__



/****************************************************************************
Copyright (c) 2010 cocos2d-x.orghttp://www.cocos2d-x.orgPermission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/#include "CCObject.h"
#include "CCAutoreleasePool.h"
#include "ccMacros.h"
#include "script_support/CCScriptSupport.h"NS_CC_BEGINCCObject* CCCopying::copyWithZone(CCZone *pZone)
{CC_UNUSED_PARAM(pZone);CCAssert(0, "not implement");return 0;
}/************************************************************************/
/* 构造函数                                                                     */
/************************************************************************/
CCObject::CCObject(void)
: m_nLuaID(0)
, m_uReference(1) // when the object is created, the reference count of it is 1
, m_uAutoReleaseCount(0)
{static unsigned int uObjectCount = 0;m_uID = ++uObjectCount;
}CCObject::~CCObject(void)
{// if the object is managed, we should remove it// from pool managerif (m_uAutoReleaseCount > 0){CCPoolManager::sharedPoolManager()->removeObject(this);}// if the object is referenced by Lua engine, remove itif (m_nLuaID){CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptObjectByCCObject(this);}else{CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();if (pEngine != NULL && pEngine->getScriptType() == kScriptTypeJavascript){pEngine->removeScriptObjectByCCObject(this);}}
}CCObject* CCObject::copy()
{return copyWithZone(0);
}//当引用计数为0时,释放对象 delete
void CCObject::release(void)
{CCAssert(m_uReference > 0, "reference count should greater than 0");--m_uReference;if (m_uReference == 0){delete this;}
}/************************************************************************/
/* 引用计数         +1 标记对象被引用                                                           */
/************************************************************************/
void CCObject::retain(void)
{CCAssert(m_uReference > 0, "reference count should greater than 0");++m_uReference;
}//将对象添加到释放池中
CCObject* CCObject::autorelease(void)
{CCPoolManager::sharedPoolManager()->addObject(this);return this;
}//判断是否单引用 
bool CCObject::isSingleReference(void) const
{return m_uReference == 1;
}unsigned int CCObject::retainCount(void) const
{return m_uReference;
}bool CCObject::isEqual(const CCObject *pObject)
{return this == pObject;
}void CCObject::acceptVisitor(CCDataVisitor &visitor)
{visitor.visitObject(this);
}NS_CC_END



注意当你autoRelease()的时候,就将对象添加到内存CCAutoreleasePool对象中,同时release(),引用计数--1;如果0,不好意思 就干掉;所以创建有些对象要记得引用计数+1,析构中销毁就对了,剩下的交给2dx内存对象模型处理;具体过程看下面代码片段:

/****************************************************************************
Copyright (c) 2010 cocos2d-x.orghttp://www.cocos2d-x.orgPermission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __AUTORELEASEPOOL_H__
#define __AUTORELEASEPOOL_H__#include "CCObject.h"
#include "CCArray.h"NS_CC_BEGIN/*** @addtogroup base_nodes* @{*/class CC_DLL CCAutoreleasePool : public CCObject
{CCArray*    m_pManagedObjectArray;    
public:CCAutoreleasePool(void);~CCAutoreleasePool(void);void addObject(CCObject *pObject);void removeObject(CCObject *pObject);void clear();
};
//自动释放池
class CC_DLL CCPoolManager
{CCArray*    m_pReleasePoolStack;    CCAutoreleasePool*                    m_pCurReleasePool;CCAutoreleasePool* getCurReleasePool();
public:CCPoolManager();~CCPoolManager();void finalize();void push();void pop();void removeObject(CCObject* pObject);void addObject(CCObject* pObject);static CCPoolManager* sharedPoolManager();static void purgePoolManager();friend class CCAutoreleasePool;
};// end of base_nodes group
/// @}NS_CC_END#endif //__AUTORELEASEPOOL_H__/****************************************************************************
Copyright (c) 2010 cocos2d-x.orghttp://www.cocos2d-x.orgPermission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "CCAutoreleasePool.h"
#include "ccMacros.h"NS_CC_BEGINstatic CCPoolManager* s_pPoolManager = NULL;//new 一个 array容器。缓存object对象
CCAutoreleasePool::CCAutoreleasePool(void)
{m_pManagedObjectArray = new CCArray();m_pManagedObjectArray->init();
}CCAutoreleasePool::~CCAutoreleasePool(void)
{CC_SAFE_DELETE(m_pManagedObjectArray);
}/************************************************************************/
/*                                                                      */
/************************************************************************/
void CCAutoreleasePool::addObject(CCObject* pObject)
{m_pManagedObjectArray->addObject(pObject);CCAssert(pObject->m_uReference > 1, "reference count should be greater than 1");++(pObject->m_uAutoReleaseCount);//释放对象 ,如果new 一个 ,那么要标记对象+1 ,回调函数retain(),否则会创建对象失败pObject->release(); // no ref count, in this case autorelease pool added.
}
//就是一个从数组中移除对象,java知道吧  List一样的
void CCAutoreleasePool::removeObject(CCObject* pObject)
{for (unsigned int i = 0; i < pObject->m_uAutoReleaseCount; ++i){m_pManagedObjectArray->removeObject(pObject, false);}
}
//释放池中所有对象,在每一帧后,message loop,将会删除autoRelease的对象
void CCAutoreleasePool::clear()
{if(m_pManagedObjectArray->count() > 0){//CCAutoreleasePool* pReleasePool;
#ifdef _DEBUGint nIndex = m_pManagedObjectArray->count() - 1;
#endifCCObject* pObj = NULL;CCARRAY_FOREACH_REVERSE(m_pManagedObjectArray, pObj){if(!pObj)break;--(pObj->m_uAutoReleaseCount);//(*it)->release();//delete (*it);
#ifdef _DEBUGnIndex--;
#endif}m_pManagedObjectArray->removeAllObjects();}
}//--------------------------------------------------------------------
//
// CCPoolManager
//
//--------------------------------------------------------------------CCPoolManager* CCPoolManager::sharedPoolManager()
{if (s_pPoolManager == NULL){s_pPoolManager = new CCPoolManager();}return s_pPoolManager;
}void CCPoolManager::purgePoolManager()
{CC_SAFE_DELETE(s_pPoolManager);
}CCPoolManager::CCPoolManager()
{m_pReleasePoolStack = new CCArray();    m_pReleasePoolStack->init();m_pCurReleasePool = 0;
}CCPoolManager::~CCPoolManager()
{finalize();// we only release the last autorelease pool here m_pCurReleasePool = 0;m_pReleasePoolStack->removeObjectAtIndex(0);CC_SAFE_DELETE(m_pReleasePoolStack);
}void CCPoolManager::finalize()
{if(m_pReleasePoolStack->count() > 0){//CCAutoreleasePool* pReleasePool;CCObject* pObj = NULL;CCARRAY_FOREACH(m_pReleasePoolStack, pObj){if(!pObj)break;CCAutoreleasePool* pPool = (CCAutoreleasePool*)pObj;pPool->clear();}}
}void CCPoolManager::push()
{CCAutoreleasePool* pPool = new CCAutoreleasePool();       //ref = 1m_pCurReleasePool = pPool;m_pReleasePoolStack->addObject(pPool);                   //ref = 2pPool->release();                                       //ref = 1
}void CCPoolManager::pop()
{if (! m_pCurReleasePool){return;}int nCount = m_pReleasePoolStack->count();m_pCurReleasePool->clear();if(nCount > 1){m_pReleasePoolStack->removeObjectAtIndex(nCount-1);//         if(nCount > 1)
//         {
//             m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);
//             return;
//         }m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2);}/*m_pCurReleasePool = NULL;*/
}void CCPoolManager::removeObject(CCObject* pObject)
{CCAssert(m_pCurReleasePool, "current auto release pool should not be null");m_pCurReleasePool->removeObject(pObject);
}void CCPoolManager::addObject(CCObject* pObject)
{getCurReleasePool()->addObject(pObject);
}CCAutoreleasePool* CCPoolManager::getCurReleasePool()
{if(!m_pCurReleasePool){push();}CCAssert(m_pCurReleasePool, "current auto release pool should not be null");return m_pCurReleasePool;
}NS_CC_END



下面一段摘自:http://blog.csdn.net/ring0hx/article/details/7946397

手动内存管理似乎比new/delete更麻烦,而且并没有解决一开始我们提到的函数内创建的对象的生命周期超出函数怎么办的问题。new和release需配对使用,那在函数内创建的对象返回前我们需要调用一次release,在这之前如果我们没有把对象加入到什么集合中,对象就被销毁了,和使用new/delete是一样的。自动内存管理就可以解决这个问题。CCObject有一个autorelease方法,如果一个对象在用new关键字创建之后调用了autorelease,我们就不必关心它的释放问题。CCPoolManager会在游戏的每一帧结束后自动释放这些autorelease的对象。CCPoolManager其实依然是通过引用计数来管理对象生命周期的,它里面有一个CCAutoreleasePool,我们调用CCObject的autorelease就是把自己加入到CCAutoreleasePool的对象数组里面。当每一帧结束的时候,CCPoolManager会将对象从数组中移除,如果这时候对象的引用计数为0,对象就自然被释放了。 对于用new关键字创建之后调用了autorelease的对象,不需要再release一次。

cocos2dx中的大部分对象都可以通过静态工厂方法来创建出这种会自动释放的对象,这是cocos2dx的一条规则,我们自己实现的类最好也遵循这样的规则,以免引起其他开发人员误会。如果一个对象是通过类的静态方法创建而不是new出来的,我们就不需要release它。

其实这里的自动并没有我们想得那么好,对于像C#,Java这种托管语言,虚拟机为你完成了所有内存管理工作,程序员完全从内存分配和释放中解脱了出来。cocos2dx的autorelease只不过每帧结束后自动在为我们释放了一次对象, 如果我们希望创建的对象在下一帧仍然可以使用,我们需要显式地retain一下这个对象或者把对象加入到集合中(集合会帮我们retain一次)。既然retain了,我们还是不能忘记在适当的地方release。比较常见的用法是创建一个autorelease对象作为类成员变量,我们在通过静态方法得到实例的指针后除了赋值给类成员,还要retain一次,然后在类的析构函数中release一次。如果没有retain,以后使用该成员的时候就会因为对象被销毁而发生内存访问错误,这是新手很容易遇到的陷阱。

想了解更多 你也可以看这里,个人觉得这里翻译,以及写的都不错:http://my.oschina.net/wangxuanyihaha/blog/131735



综上所述,2dc引擎中创建了对象 记得添加到对象池中,以便在合适的时机2dx引擎帮你回收内存,其实这个也不是大问题 洁身自好就没事的( 上了厕所要搽干净pp) 你觉得呢?ps:本系列文章会持续更新,后期就会直接根据各个模块单独demo上起,最后出个游戏demo,有问题的请留言,互相学习












转载于:https://my.oschina.net/chenleijava/blog/183167

相关文章:

读8篇论文,梳理BERT相关模型进展与反思

作者 | 陈永强来源 | 微软研究院AI头条&#xff08;ID:MSRAsia)【导读】BERT 自从在 arXiv 上发表以来获得了很大的成功和关注&#xff0c;打开了 NLP 中 2-Stage 的潘多拉魔盒。随后涌现了一大批类似于“BERT”的预训练&#xff08;pre-trained&#xff09;模型&#xff0c;有…

Dlib库中实现正脸人脸检测的测试代码

Dlib库中提供了正脸人脸检测的接口&#xff0c;这里参考dlib/examples/face_detection_ex.cpp中的代码&#xff0c;通过调用Dlib中的接口&#xff0c;实现正脸人脸检测的测试代码&#xff0c;测试代码如下&#xff1a;#include "funset.hpp" #include <string>…

20189317 《网络攻防技术》 第二周作业

一.黑客信息 &#xff08;1&#xff09;国外黑客 1971年&#xff0c;卡普尔从耶鲁大学毕业。在校期间&#xff0c;他专修心理学、语言学以及计算机学科。也就是在这时他开始对计算机萌生兴趣。他继续到研究生院深造。20世纪60年代&#xff0c;退学是许多人的一个选择。只靠知识…

centos 6.4 SVN服务器多个项目的权限分组管理

根据本博客中的cent OS 6.4下的SVN服务器构建 一文&#xff0c;搭建好SVN服务器只能管理一个工程&#xff0c;如何做到不同的项目&#xff0c;多个成员的权限管理分配呢&#xff1f;一 需求开发服务器搭建好SVN服务器&#xff0c;不可能只管理一个工程项目&#xff0c;如何做到…

cifar数据集介绍及到图像转换的实现

CIFAR是一个用于普通物体识别的数据集。CIFAR数据集分为两种&#xff1a;CIFAR-10和CIFAR-100。The CIFAR-10 and CIFAR-100 are labeled subsets of the 80 million tiny images dataset. They were collected by Alex Krizhevsky, Vinod Nair, and Geoffrey Hinton.CIFAR-10由…

取代Python?Rust凭什么

作者 | Nathan J. Goldbaum译者 | 弯月&#xff0c;责编 | 屠敏来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;【导语】Rust 也能实现神经网络&#xff1f;在前一篇帖子中&#xff0c;作者介绍了MNIST数据集以及分辨手写数字的问题。在这篇文章中&#xff0c;他将…

【Mac】解决「无法将 chromedriver 移动到 /usr/bin 目录下」问题

问题描述 在搭建 Selenium 库 ChromeDriver 爬虫环境时&#xff0c;遇到了无法将 chromedriver 移动到 /usr/bin 目录下的问题&#xff0c;如下图&#xff1a; 一查原来是因为系统有一个 System Integrity Protection (SIP) 系统完整性保护&#xff0c;如果此功能不关闭&#…

【译文】怎样让一天有36个小时

作者&#xff1a;Jon Bischke原文地址&#xff1a;How to Have a 36 Hour Day 你经常听人说“真希望一天能多几个小时”或者类似的话吗&#xff1f;当然&#xff0c;现实中我们每天只有24小时。这么说吧&#xff0c;人和人怎样度过这24个小时是完全不同的。到现在这样的说法已经…

Dlib库中实现正脸人脸关键点(landmark)检测的测试代码

Dlib库中提供了正脸人脸关键点检测的接口&#xff0c;这里参考dlib/examples/face_landmark_detection_ex.cpp中的代码&#xff0c;通过调用Dlib中的接口&#xff0c;实现正脸人脸关键点检测的测试代码&#xff0c;测试代码如下&#xff1a;/* reference: dlib/examples/face_l…

LeetCode--004--寻找两个有序数组的中位数(java)

转自https://blog.csdn.net/chen_xinjia/article/details/69258706 其中&#xff0c;N14,N26,size4610. 1&#xff0c;现在有的是两个已经排好序的数组&#xff0c;结果是要找出这两个数组中间的数值&#xff0c;如果两个数组的元素个数为偶数&#xff0c;则输出的是中间两个元…

开源sk-dist,超参数调优仅需3.4秒,sk-learn训练速度提升100倍

作者 | Evan Harris译者 | Monanfei编辑 | Jane 出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100)【导语】这篇文章为大家介绍了一个开源项目——sk-dist。在一台没有并行化的单机上进行超参数调优&#xff0c;需要 7.2 分钟&#xff0c;而在一百多个核心的 Spark 群集…

Windows和Linux下通用的线程接口

对于多线程开发&#xff0c;Linux下有pthread线程库&#xff0c;使用起来比较方便&#xff0c;而Windows没有&#xff0c;对于涉及到多线程的跨平台代码开发&#xff0c;会带来不便。这里参考网络上的一些文章&#xff0c;整理了在Windows和Linux下通用的线程接口。经过测试&am…

MySQL 性能调优的10个方法

MYSQL 应该是最流行了 WEB 后端数据库。WEB 开发语言最近发展很快&#xff0c;PHP&#xff0c; Ruby, Python, Java 各有特点&#xff0c;虽然 NOSQL 最近越來越多的被提到&#xff0c;但是相信大部分架构师还是会选择 MYSQL 来做数据存储。MYSQL 如此方便和稳定&#xff0c;以…

他们用卷积神经网络,发现了名画中隐藏的秘密

作者 | 神经小刀来源 |HyperAI超神经&#xff08; ID: HyperAI&#xff09;导语&#xff1a;著名的艺术珍品《根特祭坛画》&#xff0c;正在进行浩大的修复工作&#xff0c;以保证现在的人们能感受到这幅伟大的巨制&#xff0c;散发出的灿烂光芒。而随着技术的进步&#xff0c;…

机器学习公开课~~~~mooc

https://class.coursera.org/ntumlone-001/class/index

DLM:微信大规模分布式n-gram语言模型系统

来源 | 微信后台团队Wechat & NUS《A Distributed System for Large-scale n-gram Language Models at Tencent》分布式语言模型&#xff0c;支持大型n-gram LM解码的系统。本文是对原VLDB2019论文的简要翻译。摘要n-gram语言模型广泛用于语言处理&#xff0c;例如自动语音…

Ubuntu14.04 64位机上安装cuda8.0+cudnn5.0操作步骤

查看Ubuntu14.04 64位上显卡信息&#xff0c;执行&#xff1a;lspci | grep -i vga lspci -v -s 01:00.0 nvidia-smi第一条此命令可以显示一些显卡的相关信息&#xff1b;如果想查看某个详细信息&#xff0c;可以执行第二条命令;如果是NVIDIA卡&#xff0c; 可继续执行第三条命…

SQLI DUMB SERIES-5

less5 &#xff08;1&#xff09;输入单引号&#xff0c;回显错误&#xff0c;说明存在注入点。输入的Id被一对单引号所包围&#xff0c;可以闭合单引号 &#xff08;2&#xff09;输入正常时&#xff1a;?id1 说明没有显示位&#xff0c;因此不能使用联合查询了&#xff1b;可…

javascript RegExp

http://www.w3schools.com/jsref/jsref_obj_regexp.asp声明-------------modifiers&#xff1a;{i,g,m}1. var pattnew RegExp(pattern,modifiers);2. var patt/pattern/modifiers;------------------------例子&#xff1a;var str "Visit W3Schools"; //两…

Ubuntu14.04 64位机上安装OpenCV2.4.13(CUDA8.0)版操作步骤

Ubuntu14.04 64位机上安装CUDA8.0的操作步骤可以参考http://blog.csdn.net/fengbingchun/article/details/53840684&#xff0c;这里是在已经正确安装了CUDA8.0的基础上安装OpenCV2.4.13(CUDA8.0)操作步骤&#xff1a;1. 从http://opencv.org/downloads.html 下载OpenCV2.…

一篇文章能够看懂基础代码之CSS

web页面主要分为三块内容&#xff1a;js&#xff1a;控制用户行为和执行代码行为html元素&#xff1a;控制页面显示哪些控件&#xff08;例如按钮&#xff0c;输入框&#xff0c;文本等&#xff09;css&#xff1a;控制如何显示页面上的空间&#xff0c;例如布局&#xff0c;颜…

谷歌NIPS论文Transformer模型解读:只要Attention就够了

作者 | Sherwin Chen译者 | Major&#xff0c;编辑 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;导读&#xff1a;在 NIPS 2017 上&#xff0c;谷歌的 Vaswani 等人提出了 Transformer 模型。它利用自我注意&#xff08;self-attention&#xff09;来计算其…

中国移动与苹果联姻 三星在华霸主地位或遭取代

据国外媒体12月24日报道&#xff0c;在各方的期待下&#xff0c;苹果终于宣布中国移动将于2014年1月17日开始销售支持其网络的iPhone手机。而中国移动也将于12 月25日开始正式接受预定。作为中国以及世界最大的移动运营商&#xff0c;中国移动与苹果的合作&#xff0c;将会帮助…

二维码Data Matrix编码、解码使用举例

二维码Data Matrix的介绍见&#xff1a; http://blog.csdn.net/fengbingchun/article/details/44279967 &#xff0c;这里简单写了个生成二维码和对二维码进行识别的测试例子&#xff0c;如下&#xff1a;int test_data_matrix_encode() {std::string str "中国_abc_DEF…

PDF文件如何转成markdown格式

百度上根据pdf转makrdown为关键字进行搜索&#xff0c;结果大多数是反过来的转换&#xff0c;即markdown文本转PDF格式。 但是PDF转markdown的解决方案很少。 正好我工作上有这个需求&#xff0c;所以自己实现了一个解决方案。 下图是一个用PDF XChange Editor打开的PDF文件&am…

关于SAP BW提示“Carry out repairs in non-original only

为什么80%的码农都做不了架构师&#xff1f;>>> 这个提示是由于你在生产系统&#xff08;正式系统&#xff09;里面修改了一些东西&#xff0c;才提示"Carry out repairs in non-original system only if they are urgent"这个警告&#xff0c;理论上我们…

windows7 64位机上安装配置CUDA7.5(或8.0)+cudnn5.0操作步骤

按照官网文档 http://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html#axzz4TpI4c8vf 进行安装&#xff1a;在windows7上安装cuda8.0/cuda7.5的系统需求&#xff1a;(1)、ACUDA-capable GPU(本机显卡为GeForce GT 640M)&#xff1b;(2)、A support…

多重影分身:一套代码如何生成多个小程序?

前言 影分身术&#xff0c;看过火影的都知道&#xff0c;一个本体&#xff0c;多个分身。 大家肯定要问了&#xff0c;那小程序开发跟影分身术也能扯上关系&#xff1f;没错&#xff0c;那自然就是&#xff1a;一套代码&#xff0c;多个小程序啦。 各位先别翻白眼&#xff0c;且…

TensorFlow全家桶的落地开花 | 2019 Google开发者日

作者 | 唐小引写于上海世博中心出品 | GDD 合作伙伴 CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;Android 10 原生支持 5G&#xff0c;Flutter 1.9、Dart 2.5 正式发布这是 Google Developer Days 在中国的第四年&#xff0c;从 2016 年 Google Developers 中国网站正式…

css的background

背景属性——background是css中的核心属性。你应该对它有充分的了解。这篇文章详细讨论了background的所有相关属性&#xff0c;甚至包括background-p_w_upload&#xff0c;还为我们介绍了它在即将到来的CSS3中的样子&#xff0c;还有那些新加入的背景属性。使用CSS2中的背景属…