Sdílet prostřednictvím


Domény aplikací

Poznámka:

Tento článek je specifický pro rozhraní .NET Framework. Nevztahuje se na novější implementace .NET, včetně .NET 6 a novějších verzí.

Operační systémy a běhová prostředí obvykle poskytují určitou formu izolace mezi aplikacemi. Systém Windows například používá procesy k izolaci aplikací. Tato izolace je nezbytná k zajištění toho, aby kód spuštěný v jedné aplikaci nemohl nepříznivě ovlivnit jiné nesouvisející aplikace.

Domény aplikací poskytují hranici izolace pro zabezpečení, spolehlivost a správu verzí a pro uvolňování sestavení. Domény aplikací se obvykle vytvářejí hostiteli modulu runtime, kteří zodpovídají za spouštění modulu CLR (Common Language Runtime) před spuštěním aplikace.

Výhody izolace aplikací

V minulosti se hranice procesů používaly k izolaci aplikací běžících na stejném počítači. Každá aplikace se načte do samostatného procesu, který izoluje aplikaci od ostatních aplikací spuštěných na stejném počítači.

Aplikace jsou izolované, protože adresy paměti jsou relativní vzhledem k procesu; ukazatel paměti předaný z jednoho procesu do druhého nelze v cílovém procesu použít smysluplným způsobem. Kromě toho není možné provádět přímá volání mezi dvěma procesy. Místo toho musíte použít proxy servery, které poskytují úroveň nepřímých závislostí.

Před spuštěním spravovaného kódu je nutné provést ověřovací proces (pokud správce nepovolil oprávnění k vynechání ověření). Proces ověření určuje, jestli se kód může pokusit o přístup k neplatným adresům paměti, nebo provést nějakou jinou akci, která by mohla způsobit, že proces, ve kterém běží, nebude správně fungovat. Kód, který projde ověřovacím testem, je o tom, že je bezpečný. Možnost ověřit kód jako typově bezpečný umožňuje modulu CLR (Common Language Runtime) poskytovat stejně velkou úroveň izolace jako hranice procesu s mnohem nižšími náklady na výkon.

Domény aplikací poskytují bezpečnější a všestrannější jednotku zpracování, kterou může modul CLR (Common Language Runtime) použít k zajištění izolace mezi aplikacemi. V jednom procesu můžete spustit několik domén aplikace se stejnou úrovní izolace, která by existovala v samostatných procesech, ale bez dalších režijních nákladů na provádění volání mezi procesy nebo přepínání mezi procesy. Schopnost spouštět více aplikací v rámci jednoho procesu výrazně zvyšuje škálovatelnost serveru.

Izolace aplikací je také důležitá pro zabezpečení aplikací. Ovládací prvky z několika webových aplikací můžete například spouštět v jednom procesu prohlížeče tak, aby ovládací prvky nemohly přistupovat k datům a prostředkům ostatních.

Izolace poskytovaná doménami aplikací má následující výhody:

  • Chyby v jedné aplikaci nemohou ovlivnit jiné aplikace. Protože typově bezpečný kód nemůže způsobit chyby paměti, použití domén aplikace zajišťuje, že kód spuštěný v jedné doméně nemůže ovlivnit jiné aplikace v procesu.

  • Jednotlivé aplikace je možné zastavit bez zastavení celého procesu. Použití domén aplikací umožňuje uvolnit kód spuštěný v jedné aplikaci.

    Poznámka:

    Nelze uvolnit jednotlivá sestavení nebo typy. Uvolnit lze pouze úplnou doménu.

  • Kód spuštěný v jedné aplikaci nemůže přímo přistupovat k kódu nebo prostředkům z jiné aplikace. Modul CLR (Common Language Runtime) tuto izolaci vynucuje tím, že brání přímým voláním mezi objekty v různých doménách aplikace. Objekty předávané mezi doménami se buď zkopírují, nebo se k němu přistupují proxy serverem. Pokud je objekt zkopírován, volání objektu je místní. To znamená, že volající i objekt, na který se odkazuje, jsou ve stejné doméně aplikace. Pokud se k objektu přistupuje přes proxy server, volání objektu je vzdálené. V tomto případě se volající a objekt, na který odkazuje, nacházejí v různých doménách aplikace. Volání mezi doménou používají stejnou infrastrukturu vzdáleného volání jako volání mezi dvěma procesy nebo mezi dvěma počítači. Proto musí být metadata odkazovaného objektu dostupná pro obě domény aplikace, aby bylo možné správně zkompilovat volání metody JIT. Pokud volající doména nemá přístup k metadatům pro objekt, který je volána, kompilace může selhat s výjimkou typu FileNotFoundException. Další informace naleznete v tématu Vzdálené objekty. Mechanismus pro určení přístupu k objektům napříč doménami je určen objektem. Další informace najdete na webu System.MarshalByRefObject.

  • Chování kódu je vymezeno aplikací, ve které běží. Jinými slovy, doména aplikace poskytuje nastavení konfigurace, jako jsou zásady verze aplikace, umístění všech vzdálených sestavení, ke kterým přistupuje, a informace o tom, kde najít sestavení načtená do domény.

  • Oprávnění udělená kódu můžou být řízena doménou aplikace, ve které je kód spuštěný.

Domény a sestavení aplikací

Tato část popisuje vztah mezi doménami aplikace a sestaveními. Před spuštěním kódu, který obsahuje, je nutné načíst sestavení do domény aplikace. Spuštění typické aplikace způsobí načtení několika sestavení do domény aplikace.

Způsob načtení sestavení určuje, jestli může být kompilovaný kód ZA běhu (JIT) sdílen více doménami aplikace v procesu a zda je možné sestavení uvolnit z procesu.

  • Pokud je načteno sestavení neutrální z domény, můžou všechny domény aplikace, které sdílejí stejnou sadu udělení zabezpečení, sdílet stejný kód zkompilovaný jit, což snižuje paměť vyžadovanou aplikací. Sestavení však nelze nikdy uvolnit z procesu.

  • Pokud sestavení není načteno v doméně neutrální, musí být zkompilováno JIT v každé doméně aplikace, ve které je načtena. Sestavení však může být uvolněno z procesu uvolněním všech domén aplikace, ve kterých je načten.

Hostitel modulu runtime určuje, zda se mají sestavení načítat jako neutrální doména, když načte modul runtime do procesu. U spravovaných aplikací použijte LoaderOptimizationAttribute atribut na metodu vstupního bodu pro proces a zadejte hodnotu z přidruženého LoaderOptimization výčtu. Pro nespravované aplikace, které hostují modul CLR (Common Language Runtime), zadejte příslušný příznak při volání CorBindToRuntimeEx – metoda funkce .

Existují tři možnosti načítání sestavení neutrálních pro doménu:

  • LoaderOptimization.SingleDomain nenačte žádná sestavení jako doménově neutrální, s výjimkou knihovny Mscorlib, která je vždy načtena jako neutrální doména. Toto nastavení se nazývá jedna doména, protože se běžně používá, když hostitel spouští v procesu pouze jednu aplikaci.

  • LoaderOptimization.MultiDomain načte všechna sestavení jako doménově neutrální. Toto nastavení použijte, pokud v procesu existuje více domén aplikace, z nichž všechny běží stejný kód.

  • LoaderOptimization.MultiDomainHost načte sestavení se silným názvem jako doménově neutrální, pokud byly nainstalovány a všechny jejich závislosti byly nainstalovány v globální mezipaměti sestavení. Jiná sestavení jsou načtena a JIT kompilována samostatně pro každou doménu aplikace, ve které jsou načteny, a proto je možné je z procesu uvolnit. Toto nastavení použijte při spuštění více než jedné aplikace ve stejném procesu nebo pokud máte kombinaci sestavení, která jsou sdílena mnoha doménami aplikace a sestaveními, které je potřeba z procesu uvolnit.

Zkompilovaný kód JIT nelze sdílet pro sestavení načtená do kontextu načtení, pomocí LoadFrom metody Assembly třídy nebo načtena z obrázků pomocí přetížení Load metody, která určují pole bajtů.

Sestavení zkompilovaná do nativního kódu pomocí Ngen.exe (Generátor nativních bitových kopii) je možné sdílet mezi doménami aplikace, pokud jsou načteny do procesu poprvé, když jsou načteny do procesu.

Kód zkompilovaný JIT pro sestavení, které obsahuje vstupní bod aplikace, je sdílen pouze v případě, že lze sdílet všechny její závislosti.

Sestavení neutrální domény může být zkompilováno jit vícekrát. Pokud jsou například sady grantů zabezpečení dvou domén aplikace odlišné, nemůžou sdílet stejný kód zkompilovaný JIT. Každou kopii sestavení JIT kompilovaného jit lze však sdílet s jinými doménami aplikace, které mají stejnou sadu udělení.

Když se rozhodnete, jestli se mají sestavení načítat jako doménově neutrální, musíte učinit kompromis mezi snížením využití paměti a dalšími faktory výkonu.

  • Přístup ke statickým datům a metodám je pro sestavení neutrální v doméně pomalejší, protože je potřeba izolovat sestavení. Každá doména aplikace, která přistupuje k sestavení, musí mít samostatnou kopii statických dat, aby se zabránilo odkazům na objekty ve statických polích překračovat hranice domény. Modul runtime proto obsahuje další logiku pro směrování volajícího na příslušnou kopii statických dat nebo metody. Tato další logika zpomaluje volání.

  • Všechny závislosti sestavení musí být umístěny a načteny, pokud je sestavení načteno do domény neutrální, protože závislost, která nelze načíst doménově neutrální, brání načtení sestavení neutrální domény.

Domény aplikací a vlákna

Doména aplikace tvoří hranici izolace pro zabezpečení, správu verzí, spolehlivost a uvolnění spravovaného kódu. Vlákno je konstruktor operačního systému používaný modulem CLR (Common Language Runtime) ke spuštění kódu. Za běhu se veškerý spravovaný kód načte do domény aplikace a spouští se jedním nebo více spravovanými vlákny.

Mezi doménami aplikací a vlákny neexistuje korelace 1:1. V každém okamžiku se může v jedné doméně aplikace spustit několik vláken a konkrétní vlákno se neomezuje na jednu doménu aplikace. To znamená, že vlákna jsou bezplatná pro hranice domény aplikace; Pro každou doménu aplikace se nevytvořilo nové vlákno.

V každém okamžiku se každé vlákno spustí v doméně aplikace. V jakékoli dané doméně aplikace může být spuštěna nula, jedna nebo více vláken. Modul runtime sleduje, která vlákna běží ve kterých doménách aplikace. Doménu, ve které se vlákno spouští, můžete kdykoli vyhledat voláním Thread.GetDomain metody.

Domény aplikací a jazykové verze

Jazyková verze, která je reprezentována objektem CultureInfo , je přidružena k podprocesům. Jazykovou verzi přidruženou k aktuálně spuštěné podprocesu můžete získat pomocí CultureInfo.CurrentCulture vlastnosti a získat nebo nastavit jazykovou verzi přidruženou k aktuálně spuštěné vlákno pomocí Thread.CurrentCulture vlastnosti. Pokud je jazyková verze přidružená k vláknu explicitně nastavena pomocí Thread.CurrentCulture vlastnosti, bude nadále přidružena k ho vláknu, když vlákno překročí hranice domény aplikace. V opačném případě je jazyková verze přidružená k vláknu v libovolném okamžiku určena hodnotou CultureInfo.DefaultThreadCurrentCulture vlastnosti v doméně aplikace, ve které je vlákno spuštěno:

  • Pokud hodnota vlastnosti není null, jazyková verze vrácená vlastností je přidružena k vláknu (a proto vrácena Thread.CurrentCulture vlastnostmi a CultureInfo.CurrentCulture vlastnosti).

  • Pokud je nullhodnota vlastnosti , aktuální systémová jazyková verze je přidružena k vláknu.

Programování s doménami aplikací

Domény aplikací se obvykle vytvářejí a manipulují programově hostiteli modulu runtime. Někdy se ale může stát, že aplikace bude chtít pracovat i s doménami aplikací. Například aplikační program by mohl načíst komponentu aplikace do domény, aby mohla uvolnit doménu (a komponentu), aniž by bylo nutné zastavit celou aplikaci.

Jedná se AppDomain o programové rozhraní pro domény aplikací. Tato třída obsahuje metody pro vytváření a uvolnění domén, vytváření instancí typů v doménách a registraci pro různá oznámení, jako je například uvolnění domény aplikace. Následující tabulka uvádí běžně používané AppDomain metody.

AppDomain – metoda Popis
CreateDomain Vytvoří novou doménu aplikace. Doporučuje se použít přetížení této metody, která určuje AppDomainSetup objekt. Toto je upřednostňovaný způsob nastavení vlastností nové domény, jako je základ aplikace nebo kořenový adresář pro aplikaci; umístění konfiguračního souboru pro doménu; a cestu hledání, kterou modul CLR (Common Language Runtime) používá k načtení sestavení do domény.
ExecuteAssembly a ExecuteAssemblyByName Spustí sestavení v doméně aplikace. Jedná se o metodu instance, takže ji můžete použít ke spuštění kódu v jiné doméně aplikace, na kterou máte odkaz.
CreateInstanceAndUnwrap Vytvoří instanci zadaného typu v doméně aplikace a vrátí proxy server. Tuto metodu použijte, chcete-li zabránit načtení sestavení obsahujícího vytvořený typ do volající sestavení.
Unload Provede řádné vypnutí domény. Doména aplikace není uvolněna, dokud se nezastaví všechna vlákna spuštěná v doméně nebo už nejsou v doméně.

Poznámka:

Modul CLR (Common Language Runtime) nepodporuje serializaci globálních metod, takže delegáty nelze použít ke spouštění globálních metod v jiných doménách aplikace.

Nespravovaná rozhraní popsaná ve specifikaci rozhraní hostování common language runtime také poskytují přístup k doménám aplikace. Hostitelé modulu runtime můžou k vytvoření a získání přístupu k doménám aplikace v rámci procesu používat rozhraní z nespravovaného kódu.

Proměnná prostředí COMPLUS_LoaderOptimization

Proměnná prostředí, která nastavuje výchozí zásady optimalizace zavaděče spustitelné aplikace.

Syntaxe

COMPLUS_LoaderOptimization = 1

Poznámky

Typická aplikace před spuštěním kódu, který obsahují, načte do domény aplikace několik sestavení.

Způsob, jakým je sestavení načteno, určuje, zda může být jeho za běhu zkompilovaný kód (JIT) sdílen více doménami aplikace v procesu.

  • Pokud je sestavení načteno v doméně neutrální, můžou všechny domény aplikace, které sdílejí stejnou sadu udělení zabezpečení, sdílet stejný kód zkompilovaný PODLE POTŘEBY. Tím se sníží paměť vyžadovaná aplikací.

  • Pokud sestavení není načteno v doméně neutrální, musí být zkompilováno JIT v každé doméně aplikace, ve které je načteno, a zavaděč nesmí sdílet interní prostředky napříč doménami aplikace.

Pokud je nastavená hodnota 1, příznak prostředí COMPLUS_LoaderOptimization vynutí, aby hostitel modulu runtime načetl všechna sestavení nedoménově neutrálním způsobem, který se označuje jako SingleDomain. SingleDomain nenačte žádná sestavení jako doménově neutrální, s výjimkou knihovny Mscorlib, která je vždy načtena doménově neutrální. Toto nastavení se nazývá jedna doména, protože se běžně používá, když hostitel spouští v procesu pouze jednu aplikaci.

Upozornění

Příznak prostředí COMPLUS_LoaderOptimization byl navržen tak, aby se používal ve scénářích diagnostiky a testování. Zapnutí příznaku může způsobit závažné zpomalení a zvýšení využití paměti.

Příklad kódu

Chcete-li vynutit, aby všechna sestavení nebyla načtena jako neutrální doména pro službu IISADMIN, lze dosáhnout připojením COMPLUS_LoaderOptimization=1 k více řetězcové hodnotě prostředí v klíči HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\IISADMIN.

Key = HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\IISADMIN
Name = Environment
Type = REG_MULTI_SZ
Value (to append) = COMPLUS_LoaderOptimization=1

Viz také