`
qiezi
  • 浏览: 500609 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

D语言 在栈上分配对象 以及 无需GC拖管对象

    博客分类:
  • D
阅读更多
一、栈上分配对象

C++可以轻易实现在栈上和堆上分配对象,例如下面的代码:
class Foo{};

Foo foo;  //在栈上分配
Foo* foo = new Foo; //在堆上分配

在栈上分配对象是C++相较于java的一大优势,可以轻松实现RAII。

D语言也可以实现这2种分配方式:
Foo foo = new Foo; // 在GC堆上分配
scope Foo foo = new Foo; // 在栈上分配 

C++和D在栈上分配的对象,在分配时都会调用构造函数,超出作用域时都会自动析构。

这里顺便提一下0.175版以前,D的栈上对象的一个小陷阱:
scope Foo foo1 = new Foo;
scope Foo foo2 = new Foo;
scope Foo foo3 = foo1;

用了3个scope关键字,但实际上只有2个对象需要。0.175版以前,对象实际上是分配在堆上的,程序会死锁在这里。0.175版的scope对象真正在栈上分配,这个BUG也改掉了。

二、无需GC拖管的对象

C++除了在栈上和堆上分配对象以外,还支持一种由用户分配空间的方式,用户需要分配出一段内存空间,并且自己调用placement new。

char* mem = new char[sizeof(Foo)];
Foo* foo = new(mem)Foo;
foo->~Foo();
delete[] mem;

D语言同样支持这种低层操作,以下代码摘自: http://www.digitalmars.com/techtips/class_objects.html
	import std.c.stdlib;
	import std.outofmemory;

	// This is part of the D internal runtime library support
	extern (C) void _d_callfinalizer(void *p);

	class Foo
	{
	    this(int x, char c) { ... }
	    ~this() { ... }
	}

	Foo alloc_Foo(int x, char c)
	{
	    ClassInfo ci = Foo.classinfo;
	    Foo f;
	    void *p;

	    p = std.c.stdlib.malloc(ci.init.length);
	    if (!p)
		std.outofmemory._d_OutOfMemory();

	    // Initialize it
	    (cast(byte*)p)[0 .. ci.init.length] = ci.init[];

	    f = cast(Foo)p;

	    // Run constructor on it
	    f._ctor(x, c);

	    return f;
	}

	void free_Foo(Foo f)
	{   void* p = cast(void*)f;

	    if (p)
	    {
		_d_callfinalizer(p);	// call destructor
		std.c.stdlib.free(p);
	    }
	}

这在实现对象池或自定义GC时可能有帮助。使用上比C++麻烦,不过这不是个推荐使用的特性,能够驾奴这个特性的人,自然不害怕这点代码。
分享到:
评论

相关推荐

    JVM-d180f8336d784429b6d10cd1eb20c29f.pdf

    这种技术允许线程私有的对象直接在栈上分配,避免了堆内存分配的开销,并且当方法执行完毕后,对象即可自行销毁,无需进行垃圾回收,从而减轻了垃圾回收器的工作负担。 ### JVM中对象分配过程 在JVM中,对象的分配...

    超级有影响力霸气的Java面试题大全文档

    当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。 20、abstract class和interface有什么区别? ...

    JVisualVM简介与内存泄漏实战分析

    - **查看内存中的对象**:显示当前存在于堆中的对象数量及其大小,以及这些对象是由哪些类实例化的。 - **已被GC的对象**:提供已被垃圾回收器清理的对象信息,有助于理解垃圾回收的过程。 - **反向查看分配的堆栈**...

    2021春招C#.NET笔试题基础篇.pdf

    在C#中,栈(Stack)是由编译器自动分配和释放内存的区域,用于存放函数体内部定义的局部变量和引用类型变量的引用。栈内存遵循先进后出(FILO)原则,其访问速度快,但空间有限。而堆(Heap)则是无序的内存区域,...

    java 面试题 总结

    当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。 17、abstract class和interface有什么区别? 声明方法...

Global site tag (gtag.js) - Google Analytics