`
qiezi
  • 浏览: 498607 次
  • 性别: 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系列-逃逸分析、同步省略、栈上分配、标量替换1

    2. 栈上分配(Stack Allocation):如果一个对象只在方法内部使用且不发生逃逸,JVM可以选择将对象直接在栈帧中分配内存,而不是在堆上,从而减少堆分配的压力和GC的工作量。 3. 标量替换(Scalar Replacement):...

    .NET_C#_栈_堆_垃圾回收GC

    对象在堆上分配后,其生命周期由垃圾回收器(GC)管理,直至被回收。 - **用途**:存储类的实例、数组等引用类型的数据。 #### 三、栈与堆中的数据类型 - **值类型**(如整型、浮点型、结构体等):直接存储在栈中...

    java内存对象分配过程研究

    在对象创建的过程中,JVM是如何决定为对象分配多少内存的呢?这个问题涉及到JVM的具体实现以及对象本身的结构。一般而言,对象在内存中的布局可以分为三个部分: 1. **对象头(Object Header)**:存储对象自身的运行...

    golang的gc回收针对堆还是栈?变量内存分配在堆还是栈?

    引用类型的全局变量内存分配在堆上,值类型的全局变量分配在栈上 局部变量内存分配可能在栈上也可能在堆上 堆和栈的简单说明: 1.栈(操作系统):由操作系统自动分配释放 2.堆(操作系统): 一般由程序员分配释放...

    ART运行时CompactingGC为新创建对象分配内存的过程分析.docx

    非移动对象是指那些生命周期较长、位置固定的对象,例如类对象、方法对象和字段对象,以及在多次Generational Semi-Space GC后仍存活的对象。这些对象存储在Non-Moving Space中,以防止GC期间移动它们的引用失效。...

    JVM初探- 内存分配、GC原理与垃圾收集器

    另外,JVM还提供了参数控制大对象直接分配在老年代,这在一定程度上可以避免大对象在新生代和老年代之间的频繁复制,从而提升性能。 其次,垃圾回收机制中,何时回收是根据对象的存活状态来决定的。JVM采用可达性...

    C# 堆和栈的比较,提高代码性能必备

    在.NET Framework中,C#编程语言的内存管理主要涉及两个关键概念:堆(Heap)和栈(Stack)。了解它们之间的差异对于优化代码性能至关重要。堆和栈各自承担着不同的职责,它们共同协作以确保程序的正常运行。 首先...

    堆和栈详细,编程必知

    2. C++:C++在C的基础上增加了类和对象的概念,对象通常在堆上分配,以实现动态的对象生命周期管理。同时,C++引入了智能指针如`shared_ptr`和`unique_ptr`,帮助开发者更好地管理堆内存,避免内存泄漏。栈上的内存...

    探讨Java的对象是怎么在内存中产生的?

    本文将详细探讨Java对象在JVM中的创建过程以及其内存布局,帮助读者更深入地理解Java对象是如何在内存中产生的。 #### 二、对象的创建 Java对象是由类实例化的结果,当我们使用`new`关键字创建一个对象时,实际上...

    java垃圾回收(gc)机制详解

    2. 可达性分析:从一组称为“根”(如栈上的本地变量、静态字段和JNI引用)出发,遍历所有可达的对象。不可达的对象被认为是垃圾。 三、Java垃圾回收器 Java提供了多种GC类型,包括串行GC、并行GC、并发Mark Sweep...

    c#的GC垃圾回收机制详细讲解文档

    托管环境负责内存的分配和释放,使用`new`关键字创建的对象即为托管对象,它们的生命周期由GC控制。非托管代码则涉及如文件流、数据库连接或COM组件等,这些需要程序员手动管理的资源,因为GC无法直接处理它们的释放...

    什么是GC,GC是什么意思为什么要有GC

    在.NET Framework中,GC机制是公共语言运行库的一部分,它可以自动追踪和回收不再使用的对象,释放内存资源。.NET中的GC机制支持对象老化,或者说分代的概念,代是对象在内存中相对存现时期的度量单位。.NET中的GC...

    Jvm对象内存分配理解

    在分配的时候,从列表中找到一块足够大的空间分配给对象实例,并且更新到列表上的记录。 解决并发问题 在并发情况下,可能会出现正在给对象 a 分配内存,指针还没来的及进行修改,对象 b 又同时使用了原来的指针来...

    java对象创建与回收demo

    在Java编程语言中,对象是程序的基本构建块,它们代表了现实世界中的实体或概念。对象的创建和回收是Java内存管理的重要组成部分,这主要涉及到堆内存和垃圾收集机制。让我们深入探讨一下这个主题。 首先,Java对象...

    C#第八章(对象的生命周期)

    C#使用new关键字将对象分配在托管堆上,实例化结束后,垃圾回收器会负责在对象不再需要时将其销毁。垃圾回收器判断对象不再需要的依据是,对象在代码库中是否可达。一个对象如果不再有任何引用指向它,即成为垃圾...

    Java GC的过程

    总结,Java GC的过程涉及内存的自动管理,包括对象的可达性分析、垃圾收集器的选择、GC过程的执行以及调优策略。理解这些概念对于优化Java应用的性能至关重要。在实际开发中,我们需要根据应用的特性和需求来选择...

    JVM GC原理, heapsize调优

    Java虚拟机(JVM)垃圾回收(GC)是Java语言内存管理的核心机制,负责回收Java堆内存中不再使用的对象所占的空间。在JVM GC原理和heapsize调优的学习和实践过程中,需要理解多个关键概念和操作步骤,下面详细展开: ...

    GC垃圾回收机制(Word格式)

    在C#中,由于语言的特性,开发者无需手动管理内存,大部分对象的生命周期由GC自动控制。 托管代码和非托管代码是.NET框架中的两个基本概念。托管代码指的是由.NET运行时环境(CLR,Common Language Runtime)管理和...

    jdk 1.6 gc详解

    Hotspot JVM在内存分配上有三种主要方式:堆分配、栈分配和堆外分配。大多数对象在堆上的Eden区分配,部分直接分配到Old区。栈分配适用于局部变量,而堆外分配主要用于DirectByteBuffer等特殊场景,但直接使用Unsafe...

Global site tag (gtag.js) - Google Analytics