﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-时光隧道-文章分类-性能优化</title><link>http://www.cppblog.com/thinke365/category/11689.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 10 Sep 2009 23:07:41 GMT</lastBuildDate><pubDate>Thu, 10 Sep 2009 23:07:41 GMT</pubDate><ttl>60</ttl><item><title>对象生命周期</title><link>http://www.cppblog.com/thinke365/articles/95374.html</link><dc:creator>thinke365</dc:creator><author>thinke365</author><pubDate>Sat, 05 Sep 2009 07:26:00 GMT</pubDate><guid>http://www.cppblog.com/thinke365/articles/95374.html</guid><wfw:comment>http://www.cppblog.com/thinke365/comments/95374.html</wfw:comment><comments>http://www.cppblog.com/thinke365/articles/95374.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/thinke365/comments/commentRss/95374.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/thinke365/services/trackbacks/95374.html</trackback:ping><description><![CDATA[<p>是指对象从创建到被销毁的整个过程。<br><br>对象的创建有三种方式，它们的生命周期各不相同：<br>1、通过定义变量创建对象。 这种情况下变量的作用域，决定了对象的生命周期。 进入变量作用域，对象被创建，退出变量作用域，对象被销毁。 <span style="COLOR: red">global变量，在进入main之前被创建</span>，退出main之后，全局对象才会被销毁。 静态变量作用域不是整个程序，但是存储在 全局/静态数据区。因此静态变量第一次进入作用域时被创建，直到程序退出时被销毁。<br><br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>class A {<br>public:<br>&nbsp;&nbsp;&nbsp; A() {printf("A created.\n"); }<br>&nbsp;&nbsp;&nbsp; ~A() {printf("A destroyed.\n");}<br>};<br>class B {<br>public:<br>&nbsp;&nbsp;&nbsp; B() {printf("B created.\n");}<br>&nbsp;&nbsp;&nbsp; ~B() {printf("B destroyed\n");}<br>};<br>A globalA;<br>int foo(void)<br>{<br>&nbsp;&nbsp;&nbsp; printf("\nfoo()----&gt;\n");<br>&nbsp;&nbsp;&nbsp; A localA;<br>&nbsp;&nbsp;&nbsp; static B localB;<br>&nbsp;&nbsp;&nbsp; printf("foo() &lt;----\n");<br>&nbsp;&nbsp;&nbsp; return 0;<br>}<br>int main(void) {<br>&nbsp;&nbsp;&nbsp; printf("main()----&gt;\n");<br>&nbsp;&nbsp;&nbsp; foo();<br>&nbsp;&nbsp;&nbsp; foo();<br>&nbsp;&nbsp;&nbsp; printf("\nmain()&lt;----");<br>&nbsp;&nbsp;&nbsp; return 0;<br>}<br><br>输出结果为：<br>A created.<br>main()----&gt;<br>foo()----&gt;<br>A created.<br>B created.<br>foo()&lt;----<br>A destroyed.&nbsp; // 退出函数之后，局部对象才会被销毁。<br>foo()----&gt;<br>A created.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 第二次进入，静态变量不会被再次初始化。仅在第一次进入作用域时初始化<br>foo()&lt;----<br>A destroyed.<br>main()&lt;----<br>B destroyed.&nbsp;&nbsp; // 程序退出时，静态变量才会被销毁。<br>A destroyed.&nbsp;&nbsp; // 程序退出后，全局对象被销毁。。。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="FONT-SIZE: 10pt; COLOR: red"><strong>是先销毁静态变量，再销毁全局变量吗?</strong></span>还是各个编译器会有不同的实现?<br><br>中间临时变量的创建和销毁(<span style="FONT-SIZE: 10pt; COLOR: #0000ff">通常是隐式的</span>)，虽然生命周期很短，不易被开发人员察觉，但是常常是造成程序性能下降的瓶颈。<br><br></p>
<img src ="http://www.cppblog.com/thinke365/aggbug/95374.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/thinke365/" target="_blank">thinke365</a> 2009-09-05 15:26 <a href="http://www.cppblog.com/thinke365/articles/95374.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对象内存概念</title><link>http://www.cppblog.com/thinke365/articles/95350.html</link><dc:creator>thinke365</dc:creator><author>thinke365</author><pubDate>Fri, 04 Sep 2009 17:28:00 GMT</pubDate><guid>http://www.cppblog.com/thinke365/articles/95350.html</guid><wfw:comment>http://www.cppblog.com/thinke365/comments/95350.html</wfw:comment><comments>http://www.cppblog.com/thinke365/articles/95350.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/thinke365/comments/commentRss/95350.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/thinke365/services/trackbacks/95350.html</trackback:ping><description><![CDATA[<p>程序由代码和数据组成。<br><br>程序运行占用的内存一般分为如下几种：<br>1、全局/静态数据区&nbsp; // 全局变量、静态变量都放在一个区的。具体如何实现，还搞不清楚。 不论是普通的静态变量，还是类中的静态变量。<br>2、常量数据区<br>3、代码区<br>4、栈<br>5、堆<br><br><span style="FONT-SIZE: 10pt; COLOR: red">对象不一定是在堆中的</span>，如果对象是<span style="FONT-SIZE: 10pt; COLOR: #0000ff">通过函数中定义的某个变量，或者实现需要的临时变量来创建的</span>，<span style="COLOR: #ff0000">那么它是在栈上的</span>，而不是在堆里面。<br>(呵呵，没想到在性能调优的书中，把这个概念明晰化了)<br><br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>int nGlobal = 100;&nbsp; // 在全局/静态数据区<br><br>int main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp; char *pLocalString1 = "LocalString1";&nbsp; // 放在常量数据区, pLocalString指向的是常量数据区，<span style="FONT-SIZE: 10pt; COLOR: #ff0000">"LocalString1"对应的内存在常量数据区</span>，<span style="FONT-SIZE: 10pt; COLOR: #0000ff"><strong>但是 pLocalString1这个变量是在栈上的， 通过打印 &amp;pLocalString1，可以看出</strong></span>。 字符串存放在常量数据区，而且是<span style="FONT-SIZE: 10pt; COLOR: #0000ff"><strong>4个字节对齐</strong></span>的。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const int nLocalConst = 20;&nbsp; // 在常量数据区，<span style="BACKGROUND-COLOR: yellow">不是的</span>。 这个变量是存放在栈上的，只是这个变量不能修改。 如何做到的，加标记?&nbsp; 字符串才放在常量区域?<br>&nbsp;&nbsp;&nbsp;&nbsp; int *pNew = new int[5];&nbsp; <span style="FONT-SIZE: 10pt; COLOR: #0000ff">通过new (malloc)获得的是堆上的内存</span>，pNew指向了堆上的地址，*pNew[0]是指向堆上的一个内存单元。 而&amp;pNew则是栈上变量的一个地址 // 堆上分配是<span style="FONT-SIZE: 10pt; COLOR: #0000ff"><strong>按16字节对齐</strong></span>的。&nbsp;<span style="FONT-SIZE: 10pt; COLOR: #008000">这里分配的内存是20字节(实际应该占用32字节)</span>，如果再申请一个字节，会从32字节之后开始分配内存。&nbsp; <span style="FONT-SIZE: 10pt; COLOR: #ff0000">对齐的字节数可否自己定义，通过编译选项来完成吗</span>?<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>}<br><br>C语言有静态变量，C++除此之外还可以定义 类的静态变量。 <span style="FONT-SIZE: 10pt; COLOR: red">用于在类的对象之间共享数据</span>。<span style="FONT-SIZE: 10pt; COLOR: #993300">虽然也可以用全局变量做到这一点，但是会破坏类的封装性</span>。 这也是类静态变量存在的理由，呵呵，<span style="FONT-SIZE: 10pt; COLOR: #ff0000"><strong>每样设计都是基于一定的需求，而精心设计的啊</strong></span>。<br><br>虽然内存对齐会浪费一些内存，<span style="FONT-SIZE: 10pt; COLOR: #0000ff">但是CPU在对齐方式下运行比较快，所以一般对程序性能还是有好处的</span>。<br>编译时，会对成员变量进行对齐操作。&nbsp; 可以通过 #pragma pack() 设定对齐的字节数，或关闭对齐<br><br>内存泄露是 C/ C++非常需要注意的地方。&nbsp;&nbsp; <span style="FONT-SIZE: 10pt; COLOR: #0000ff">那么程序退出时，这些内存是否会被收回呢</span>?<br><br>插入*pMalloc = (char*) malloc(1);&nbsp;&nbsp; <span style="FONT-SIZE: 10pt; COLOR: #0000ff">用malloc在堆上申请了 1个字节的内存，将获得的地址记录在变量pMalloc中</span>。<br><br>malloc申请的内存需要用 free来释放， new申请的内存，则要用delete来释放。<br><br><span style="COLOR: red">栈不存在内存泄露问题</span>。 <span style="FONT-SIZE: 10pt; COLOR: #0000ff">那为什么还要用堆呢? 因为很多应用要动态地管理数据</span>。如链表，要为链表增加节点，就无法使用栈上的对象。此外<span style="FONT-SIZE: 10pt; COLOR: #0000ff">栈的大小有限制，占用内存较多的对象或数据只能分配在堆上</span>。<br><br><span style="FONT-SIZE: 10pt; COLOR: red">堆的大小一般只受限于系统有效虚拟内存的大小</span>。<br><br>栈的效率比较高，而且不会有碎片。<br><span style="FONT-SIZE: 10pt; COLOR: red">堆得效率要低些，并且会产生碎片</span>。<br><br></p>
<img src ="http://www.cppblog.com/thinke365/aggbug/95350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/thinke365/" target="_blank">thinke365</a> 2009-09-05 01:28 <a href="http://www.cppblog.com/thinke365/articles/95350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>