AppDomain的地址空间 [英] AppDomain address space

查看:373
本文介绍了AppDomain的地址空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,这个问题:做CLR规范保证code执行多个应用程序域在同一进程内将共享相同的地址空间?通过共享地址空间我的意思是指向分配的应用程序域的一个存储器将是有效的阅读和写作在相同的进程中承载的所有应用程序域。

First, the question: do CLR specifications guarantee that the code executing in multiple app domains within the same process will share the same address space? By "sharing the address space" I mean that pointers to memory allocated in one of the app domains will be valid for reading and writing across all app domains hosted inside the same process.

考虑这种自成一体的例子,说明了一个问题:该方案在一个单独的应用程序域分配工人对象。该工人分配10000整数的内存块,并用数据填充入。然后程序跨应用程序域边界来电索取指针分配的内存块,并验证它可以读取每个人的10,000项。

Consider this self-contained example illustrating the question: the program allocates a Worker object in a separate app domain. The Worker allocates a memory block for 10,000 integers, and fills it in with data. The program then calls across the app domain boundary to obtain the pointer to the allocated block, and verifies that it can read every one of the 10,000 items.

using System;
using System.Reflection;
using System.Runtime.InteropServices;

namespace crossapp {
    public class Worker : MarshalByRefObject {
        private readonly IntPtr myData;
        public const int DataLength = 10000;
        public Worker() {
            Console.Error.WriteLine(
                "Memory allocation happens in app domain '{0}'"
            ,   Assembly.GetExecutingAssembly().FullName
            );
            myData = Marshal.AllocHGlobal(sizeof(int) * DataLength);
            unsafe {
                var ptr = (int*) myData.ToPointer();
                for (var i = 0 ; i != DataLength ; i++) {
                    ptr[i] = 2*i + 1;
                }
            }
        }
        public IntPtr GetData() {
            return myData;
        }
    }
    class Program {
        static void Main() {
            var ad = AppDomain.CreateDomain("New domain");
            var wrk = (Worker)ad.CreateInstanceAndUnwrap(
                Assembly.GetExecutingAssembly().FullName
            ,   "crossapp.Worker"
            );
            var data = wrk.GetData();
            var badCount = 0;
            unsafe {
                var ptr = (int*)data.ToPointer();
                for (var i = 0 ; i != Worker.DataLength ; i++) {
                    var expect = 2*i + 1;
                    if (ptr[i] != expect) {
                        Console.Error.WriteLine(
                            "Mismatch in position {0}: {1} != {2}"
                        ,   i, expect, ptr[i]
                        );
                        badCount++;
                    }
                }
                if (badCount == 0) {
                    Console.Error.WriteLine(
                        "All {0} items have matched."
                    ,   Worker.DataLength
                    );
                } else {
                    Console.Error.WriteLine(
                        "Found {0} mismatches out of {1}."
                    ,   badCount
                    ,   Worker.DataLength
                    );
                }
            }
        }
    }
}

我跑了很多次,和它的工作每一次。直觉上它应该工作:毕竟,应用程序域都在一个单一的过程,所以他们必须共享相同的虚拟地址空间。然而,这种感觉功能,像一个漏洞,微软可能带走在任何时间。有什么在CLR的规范,确认或否认这一招的合法性?


如果你想知道为什么我问这么奇怪的问题,我找过大(以GB为单位)的数据跨应用程序域边界,在时间和空间上的开销最小的一种方式。这将是我的理想解决方案,如果我能证明其合法性。

I ran this many times, and it worked every single time. Intuitively it should work: after all, app domains are within a single process, so they must share the same virtual address space. However, this feels like an exploit of a feature that Microsoft may take away at any time. Is there something in the specification of CLR that confirms or denies legitimacy of this trick?


In case you are wondering why I am asking such a strange question, I am looking for a way of passing large (in gigabytes) amounts of data across app domain boundary, with minimal overhead in both space and time. This would be my ideal solution if I could prove its legitimacy.

推荐答案

看:<一href="http://stackoverflow.com/questions/4295894/anyone-can-explain-the-major-use-of-marshalbyrefobject">Anyone可以解释MarshalByRefObject的的主要用途。 在您的情况,您只通过一个代理,而不是实际的对象和内存不被复制。

Look at: Anyone can explain the major use of MarshalByRefObject . In your scenario, you are only passing a proxy and not the actual object and the memory is not being copied.

编辑:

  1. 在合法性!=绝招,你的黑客是通过不编组调用到另一个AppDomain中的数据破坏的AppDomain。运行时容器设置/这可能会破坏你的应用改变安全限制,如:是IIS这里面运行? (在你的情况,你是不是访问一个对象,但内存,因此它可能是没那么坏。)这是一个产品,您将可以部署在客户的网站?
  2. 我认为有通过代理编组性能问题,所以你使出的IntPtr(切出的中间人)
  3. 是不同的工人的AppDomain操纵BLOB?如果是的话,我会感到担心,最终的内存会被破坏......因为你不封送您的来电。
  4. 这是用C#创建非托管内存。如果在现实中,团块是由非托管的DLL分配的,那么你就必须确保非托管的DLL不卸载。同样,如果要部署到IIS,那么你不控制你的应用程序域'生命周期,IIS一样。这将打破你的黑客。
  5. 是的,虚拟内存是每个进程,而不是每个AppDomain,因此所有应用程序域共享相同的虚拟地址空间。
  6. 不管我保留意见,这是非常酷的:)

这篇关于AppDomain的地址空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆