论坛首页 编程语言技术论坛

在linux上替换动态库的内存变化分析

浏览 2630 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-07-23  

在linux上替换动态库的内存变化


测试static变量:
static string staticString = "123";
void queryFreezingMoney(CFmlBuf& inBuf, CFmlBuf& outBuf)
{
    string in = GetString(inBuf,"SEND_CODE");
    if (in == "1")
    {
    staticString = GetString(inBuf,"SEND_DESC");
    }
    else
    {
    outBuf.SetString("OPER_DESC",staticString);
    }
}

当send_code传入非1时,可以传入send_desc修改staticString的值,假设修改为"456"后,每次查询OPER_DESC的返回都是新的值"456"。证明static起作用。

然后,重新替换so动态库(queryFreezingMoney函数编译在动态库中),替换后和替换前的动态库中代码是完全一样,此时再调用,OPER_DESC返回"123"。证明替换动态库,即使不重启程序,也会使得全局数据区的内存重新加载。

单例和static有点相似,他们在内存区一样吗?
不一样。单例是new创建的,它在堆区;static在上一篇文章说了,在全局数据区。

所以,接着我们需要测试,替换了动态库,堆区的内存是如何变化的。

ArchQuery.h
class ArchQuery
{
public:
    static string singletonString;
};

ArchQuery.cpp
string ArchQuery::singletonString = "abc";


ArchQueryMgr.cpp
typedef Singleton<archquery::ArchQuery> ArchQueryHolder;
void queryFreezingMoney(CFmlBuf& inBuf, CFmlBuf& outBuf)
{
    string in = GetString(inBuf,"SEND_CODE");
    if (in == "1")
    {
    ArchQueryHolder::getInstance().singletonString = GetString(inBuf,"SEND_DESC");
    }
    else
    {
    outBuf.SetString("OPER_DESC",ArchQueryHolder::getInstance().singletonString);
    }
}

结论同上。
singletonString初始化为abc,可以修改为def,替换动态库后,又重新变为abc。


最后,测试单例非static变量:
ArchQuery.h
class ArchQuery
{
public:
    string singletonString;
    void setSingletonString(string str)
    {
    singletonString = str;
    }
};

ArchQueryMgr.cpp
typedef Singleton<archquery::ArchQuery> ArchQueryHolder;
void queryFreezingMoney(CFmlBuf& inBuf, CFmlBuf& outBuf)
{
    string in = GetString(inBuf,"SEND_CODE");
    if (in == "1")
    {
    ArchQueryHolder::getInstance().setSingletonString(GetString(inBuf,"SEND_DESC"));
    }
    else
    {
    outBuf.SetString("OPER_DESC",ArchQueryHolder::getInstance().singletonString);
    }
}

singletonString没有初始化值,可以通过传入SEND_DESC首先把singletonString的值设为def,替换动态库后,值依然为def!
结论,替换动态库并不能使堆区的内存变化。

总结:
1 一般的static变量,替换了动态库会重新加载
2 如果是单例的static变量,替换了动态库会重新加载
3 如果是单例的非static变量,替换了动态库不会重新加载



===================
附录:

环境:
Red Hat Enterprise Linux Server release 6.3 (Santiago)
Kernel 2.6.32-279.el6.x86_64 on an x86_64

编译器 :
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)


顺带说一下,这个问题在aix上是都会重新加载的。所以两个平台迁移的时候要注意了。

AIX Version 5.3
aix编译器:
  xlC.adt.include            9.0.0.0    C     F    C Set ++ Application
  xlC.aix50.rte             10.1.0.3    C     F    XL C/C++ Runtime for AIX 5.3
  xlC.cpp                    9.0.0.0    C     F    C for AIX Preprocessor
  xlC.msg.ZH_CN.cpp          9.0.0.0    C     F    C for AIX Preprocessor
  xlC.msg.en_US.cpp          9.0.0.0    C     F    C for AIX Preprocessor
  xlC.msg.en_US.rte         10.1.0.3    C     F    XL C/C++ Runtime
  xlC.msg.zh_CN.cpp          9.0.0.0    C     F    C for AIX Preprocessor
  xlC.rte                   10.1.0.3    C     F    XL C/C++ Runtime

===============

再附两个报错信息:

static string singletonString;// 注意,这里不能初始化,否则会报错
报错:
ArchQuery.h:15: error: invalid in-class initialization of static data member of non-integral type 'std::string'

然后ArchQuery.cpp必须定义:
string ArchQuery::singletonString;

否则会报错。

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics