मैं मुद्दों में भाग रहा हूं जब बड़ी मात्रा में स्मृति आवंटित करने पर नियंत्रण नष्ट हो जाता है और यूआई से इनपुट घटनाओं का उपयोग करके पुनर्निर्मित किया जाता है।एक निश्चित रूप से भारी WPF नियंत्रणों द्वारा उपयोग की जाने वाली एक निःशुल्क मेमोरी कैसे हो सकती है?
जाहिर है, खिड़की की सामग्री को शून्य पर सेट करना, नियंत्रण में उपयोग की गई स्मृति को मुक्त करने के लिए पर्याप्त नहीं है। अंत में यह जीसीड होगा। लेकिन इनपुट घटनाओं को नष्ट करने और निर्माण करने के लिए नियंत्रण अधिक बार मिलता है, जीसी कुछ वस्तुओं को छोड़ने लगता है।
मैं इसे इस उदाहरण के लिए खराब हो गई:
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" x:Name="window" MouseMove="window_MouseMove">
</Window>
सी #:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
private class HeavyObject : UserControl
{
private byte[] x = new byte[750000000];
public HeavyObject()
{
for (int i = 0; i++ < 99999999;) { } // just so we can follow visually in Process Explorer
Content = "Peekaboo!"; // change Content to el cheapo re-trigger MouseMove
}
}
public MainWindow()
{
InitializeComponent();
//Works 1:
//while (true)
//{
// window.Content = null;
// window.Content = new HeavyObject();
//}
}
private void window_MouseMove(object sender, MouseEventArgs e)
{
if (window.Content == null)
{
GC.Collect();
GC.WaitForPendingFinalizers();
// Works 2:
//new HeavyObject();
//window.Content = "Peekaboo!"; // change Content to el cheapo re-trigger MouseMove
//return;
window.Content = new HeavyObject();
}
else
{
window.Content = null;
}
}
}
}
यह प्रत्येक MouseMove घटना में एक ~ 750MB वस्तु (HeavyObject) का आवंटन और डाल करता है यह मुख्य विंडो की सामग्री के रूप में है। यदि कर्सर विंडो पर अभी भी रखा गया है तो सामग्री परिवर्तन अंतहीन घटना को फिर से ट्रिगर करेगा। हेवी ऑब्जेक्ट का संदर्भ इसके अगले निर्माण से पहले खींचा गया है और जीसी के लिए एक व्यर्थ प्रयास इसके अवशेषों को ट्रिगर किया गया है।
प्रोसेसएक्सप्लोरर/टास्कैन में हम क्या देख सकते हैं, यह कभी-कभी 1.5 जीबी या अधिक आवंटित होता है। यदि नहीं, तो माउस को जंगली ढंग से ले जाएं और विंडो छोड़ दें और फिर से दर्ज करें। यदि आप LARGEADDRESSAWARE के बिना x86 के लिए संकलित करते हैं, तो आपको इसके बजाय आउटऑफमेमरीएक्सप्शन मिलेगा (सीमा ~ 1.3 जीबी)।
यदि आप या तो माउस इनपुट (असम्बद्ध अनुभाग "वर्क्स 1") के बिना एक अंतहीन पाश में हेवी ऑब्जेक्ट आवंटित करते हैं तो आप इस व्यवहार का सामना नहीं करेंगे या यदि आप माउस इनपुट द्वारा आवंटन को ट्रिगर करते हैं लेकिन ऑब्जेक्ट को ऑब्जेक्ट में नहीं डालते दृश्य पेड़ (असुविधा seciton "वर्क्स 2")।
तो मुझे लगता है कि दृश्य वृक्ष आलसी मुक्त संसाधनों के साथ इसका कुछ संबंध है। लेकिन फिर एक और अजीब प्रभाव है: यदि कर्सर के दौरान 1.5 जीबी का उपभोग होता है तो खिड़की के बाहर होता है, ऐसा लगता है कि जीसी तब तक नहीं टिकेगा जब तक कि माउसमोव फिर से ट्रिगर नहीं हो जाता। कम से कम, स्मृति खपत तब तक स्थिर हो जाती है जब तक कोई और घटनाएं ट्रिगर नहीं होतीं। तो या तो वहां कोई लंबा जीवित संदर्भ है या कोई गतिविधि नहीं होने पर जीसी आलसी हो जाती है।
मेरे लिए पर्याप्त अजीब लगता है। क्या आप समझ सकते हैं कि क्या हो रहा है?
संपादित करें: रूप BalamBalam टिप्पणी की: नियंत्रण के पीछे डेटा नियंत्रण नष्ट करने से पहले dereferenced जा सकता है। यह योजना बी थी। फिर भी शायद एक और सामान्य समाधान है।
ऐसे नियंत्रण कहने से खराब कोड उपयोगी नहीं है। मैं जानना चाहता हूं कि एक ऑब्जेक्ट में मुझे कोई संदर्भ क्यों नहीं है, अगर मैं इसे संदर्भित करने के बाद कुछ टीकों के लिए अकेले यूआई छोड़ देता हूं, लेकिन अगर कोई दूसरा (जिसे उपयोगकर्ता इनपुट द्वारा बनाया गया है) तुरंत ले जाता है जगह।
मैं यह नहीं समझ सकता कि आपकी समस्या क्या है ... मान लीजिए कि आपके पास पागल कोड सिर्फ परीक्षण के लिए है। लेकिन आपने एक बात सीखी है: जीसी को मजबूर करने के प्रयास अक्सर ऐसा नहीं करते जो आपको लगता है कि वे करेंगे। –
कोड एक उदाहरण है, जिसमें दो वर्कअराउंड होते हैं जहां समस्या नहीं होगी। अनुमानों को सीमित करने के लिए। समस्या यह है: विंडो सामग्री के रूप में बड़ा नियंत्रण रखें -> माउस इनपुट ** द्वारा विंडो सामग्री के रूप में नया बड़ा नियंत्रण सेट करें ** -> एक से अधिक बड़े नियंत्रण एक बार में जीवित हैं। –
खैर, मुझे उम्मीद है कि कोई भी माउस चाल पर 750 एमबी ऑब्जेक्ट आवंटित नहीं करेगा। यह एक बहुत ही अवास्तविक परिदृश्य है, और इसलिए आपकी पूरी नींव यहां shakey है। –