Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C-sharp language specification.2004.pdf
Скачиваний:
12
Добавлен:
23.08.2013
Размер:
2.55 Mб
Скачать

Chapter 10 Basic concepts

1

namespace X

// X

2

{

 

3

class B

// X.B

4

{

 

5

class C {}

// X.B.C

6

}

 

7

namespace Y

// X.Y

8

{

 

9

class D {}

// X.Y.D

10}

11}

12

namespace X.Y

// X.Y

13

{

 

14

class E {}

// X.Y.E

15

class G<T> {

// X.Y.G<>

16

class H {}

// X.Y.G<>.H

17

}

 

18

class G<S,T> {

// X.Y.G<,>

19

class H<U> {}

// X.Y.G<,>.H<>

20}

21}

22end example]

2310.9 Automatic memory management

24C# employs automatic memory management, which frees developers from manually allocating and freeing

25the memory occupied by objects. Automatic memory management policies are implemented by a garbage

26collector. The memory management life cycle of an object is as follows:

271. When the object is created, memory is allocated for it, the constructor is run, and the object is

28considered live.

292. If no part of the object can be accessed by any possible continuation of execution, other than the running

30of destructors, the object is considered no longer in use, and it becomes eligible for destruction. [Note:

31Implementations might choose to analyze code to determine which references to an object can be used in

32the future. For instance, if a local variable that is in scope is the only existing reference to an object, but

33that local variable is never referred to in any possible continuation of execution from the current

34execution point in the procedure, an implementation might (but is not required to) treat the object as no

35longer in use. end note]

363. Once the object is eligible for destruction, at some unspecified later time the destructor (§17.12) (if any)

37for the object is run. Unless overridden by explicit calls, the destructor for the object is run once only.

384. Once the destructor for an object is run, if that object, or any part of it, cannot be accessed by any

39possible continuation of execution, including the running of destructors, the object is considered

40inaccessible and the object becomes eligible for collection.

415. Finally, at some time after the object becomes eligible for collection, the garbage collector frees the

42memory associated with that object.

43The garbage collector maintains information about object usage, and uses this information to make memory

44management decisions, such as where in memory to locate a newly created object, when to relocate an

45object, and when an object is no longer in use or inaccessible.

46Like other languages that assume the existence of a garbage collector, C# is designed so that the garbage

47collector can implement a wide range of memory management policies. For instance, C# does not require

48that destructors be run or that objects be collected as soon as they are eligible, or that destructors be run in

49any particular order, or on any particular thread.

50The behavior of the garbage collector can be controlled, to some degree, via static methods on the class

51System.GC. [Note: While not required by this specification, a Collect method might be provided on the

101

C# LANGUAGE SPECIFICATION

1GC class which requests that a collection be performed. The following examples presume the existence of

2such a method. end note]

3[Example: Since the garbage collector is allowed wide latitude in deciding when to collect objects and run

4destructors, a conforming implementation might produce output that differs from that shown by the

5following code. The program

6using System;

7class A

8{

9

~A() {

10

Console.WriteLine("Destruct instance of A");

11}

12}

13class B

14{

15

object

Ref;

16

public

B(object o) {

17

Ref = o;

18

}

 

19

~B() {

 

20

Console.WriteLine("Destruct instance of B");

21}

22}

23class Test

24{

25

static void Main() {

26

B b = new B(new A());

27

b = null;

28

GC.Collect();

29

GC.WaitForPendingFinalizers();

30}

31}

32creates an instance of class A and an instance of class B. These objects become eligible for garbage

33collection when the variable b is assigned the value null, since after this time it is impossible for any user-

34written code to access them. The output could be either

35Destruct instance of A

36Destruct instance of B

37or

38Destruct instance of B

39Destruct instance of A

40because the language imposes no constraints on the order in which objects are garbage collected.

41In subtle cases, the distinction between “eligible for destruction” and “eligible for collection” can be

42important. For example,

43using System;

44class A

45{

46

~A() {

47

Console.WriteLine("Destruct instance of A");

48

}

49

public void F() {

50

Console.WriteLine("A.F");

51

Test.RefA = this;

52}

53}

102

Chapter 10 Basic concepts

1class B

2{

3

public A Ref;

4

~B() {

5

Console.WriteLine("Destruct instance of B");

6

Ref.F();

7}

8}

9class Test

10{

11

public static A RefA;

12

public static B RefB;

13

static void Main() {

14

RefB = new B();

15

RefA = new A();

16

RefB.Ref = RefA;

17

RefB = null;

18

RefA = null;

19

// A and B now eligible for destruction

20

GC.Collect();

21

GC.WaitForPendingFinalizers();

22

// B now eligible for collection, but A is not

23

if (RefA != null)

24

Console.WriteLine("RefA is not null");

25}

26}

27In the above program, if the garbage collector chooses to run the destructor of A before the destructor of B,

28then the output of this program might be:

29Destruct instance of A

30Destruct instance of B

31A.F

32RefA is not null

33Note that although the instance of A was not in use and A's destructor was run, it is still possible for methods

34of A (in this case, F) to be called from another destructor. Also, note that running of a destructor might cause

35an object to become usable from the mainline program again. In this case, the running of B's destructor

36caused an instance of A that was previously not in use to become accessible from the live reference RefA.

37After the call to WaitForPendingFinalizers, the instance of B is eligible for collection, but the instance

38of A is not, because of the reference RefA.

39To avoid confusion and unexpected behavior, it is generally a good idea for destructors to only perform

40cleanup on data stored in their object's own fields, and not to perform any actions on referenced objects or

41static fields. end example]

4210.10 Execution order

43Execution shall proceed such that the side effects of each executing thread are preserved at critical execution

44points. A side effect is defined as a read or write of a volatile field, a write to a non-volatile variable, a write

45to an external resource, and the throwing of an exception. The critical execution points at which the order of

46these side effects shall be preserved are references to volatile fields (§17.4.3), lock statements (§15.12), and

47thread creation and termination. An implementation is free to change the order of execution of a

48C# program, subject to the following constraints:

49Data dependence is preserved within a thread of execution. That is, the value of each variable is

50computed as if all statements in the thread were executed in original program order.

51Initialization ordering rules are preserved (§17.4.4 and §17.4.5).

52The ordering of side effects is preserved with respect to volatile reads and writes (§17.4.3). Additionally,

53an implementation need not evaluate part of an expression if it can deduce that that expression’s value is

54not used and that no needed side effects are produced (including any caused by calling a method or

55accessing a volatile field). When program execution is interrupted by an asynchronous event (such as an

103

C# LANGUAGE SPECIFICATION

1exception thrown by another thread), it is not guaranteed that the observable side effects are visible in

2the original program order.

104

Соседние файлы в предмете Электротехника