केबी 4525236 के साथ GetRef की मेमोरी खपत (कचरा संग्रह) बदल गई


11

हम अपने Windows 2016 सर्वर / Windows 10 ग्राहकों पर KB4525236 स्थापित करने के बाद मेमोरी समस्याओं का अनुभव करते हैं । इस सुरक्षा फ़िक्स ने उस क्षण को बदल दिया है जब किसी फ़ंक्शन को कॉल करने के दौरान मेमोरी एकत्रित होती है GetRef

Pré KB4525236

फ़ंक्शन के माध्यम से बनाए गए प्रत्येक इंस्टेंस GetRefको उदाहरण चर के सेट होते ही कचरा एकत्र हो जाता हैnothing

पोस्ट KB4525236

फंक्शन के माध्यम से बनाए गए प्रत्येक उदाहरण GetRefको मेमोरी में रहता है और कचरा तभी एकत्र किया जाता है जब पूरा फ़ंक्शन पूरा हो जाता है । एक लूप में उदाहरण बनाते समय, यह जल्दी से जोड़ सकता है और मेमोरी से बाहर हो सकता है, खासकर 32-बिट प्रक्रिया में।

प्रशन

  • हम ऑनलाइन कुछ भी प्रासंगिक नहीं पा सकते हैं ताकि हम उसी मुद्दे का अनुभव करने वाले अन्य लोगों से पुष्टि प्राप्त करना चाहें।
    EDIT खरोंच कि: यह एक ही मुद्दा है, लेकिन अभी तक कोई समाधान नहीं है
    (vbscript.dll class_terminate बग के बाद से KB4524570 (12 नवंबर, 2019) विंडोज 10 1903)
  • अगर कोई भी काम करने योग्य समाधान को सत्यापित कर सकता है और जान सकता है, तो यह बहुत बढ़िया होगा।

POC

KB4525236 स्थापित के साथ एक उपकरण पर चल रहे स्क्रिप्ट निम्नलिखित कचरा संग्रह में अंतर दिखाता है कि कब

  • सीधे कहा जाता है: पहला उदाहरण नष्ट होने के बाद ही दूसरा उदाहरण बनता है (यह हमारा वांछित व्यवहार है)
  • के माध्यम से कहा जाता है GetRef: पहला उदाहरण नष्ट होने से पहले दूसरा उदाहरण बन जाता है, इसलिए मट्ठा में मेमोरी का उपयोग करने के दो उदाहरण हैं।

इस रूप में सहेजें: KB4525236.vbs इस प्रकार
हैं: wscript KB4525236.vbs

Dim Name, Log

Class IDummyInstance
  Dim FName
  Sub Class_Initialize
    FName = Name
    Log = Log & "Initialize " & FName & VbNewLine
  End Sub
  Sub Class_Terminate
    Log = Log & "Terminate " & FName & vbNewLine
  End Sub
End Class

Sub CreateDestroyTwoInstances
  Dim DummyInstance
  Name = "First Instance"
  Set DummyInstance = New IDummyInstance
  Set DummyInstance = Nothing
  Name = "Second Instance"
  Set DummyInstance = New IDummyInstance
  Set DummyInstance = Nothing
End Sub

Log = "(1) Direct Call :" & VbNewLine
Call CreateDestroyTwoInstances

Log = VbNewLine & Log & "(2) GetRef Call :" & vbNewLine
Set GetRefCall = GetRef ("CreateDestroyTwoInstances")
Call GetRefCall

MsgBox Log

1
@ लैंकिमार्ट - समस्या यह है कि बनाए गए इंस्टेंस को GetRef()तब तक कचरा इकट्ठा नहीं GetRef()होता है जब तक कि समाप्त न हो जाए। वह जो था उससे अलग है। हमारे पास GetRef()1000 इंस्टेंसेस बनाने के माध्यम से कॉल किए गए कार्य हैं और वे मेमोरी को कम करते रहते हैं जब तक GetRef()कि अतीत में समाप्त नहीं हो जाता है, तब तक वे लूप को निष्पादित करते समय मुक्त हो गए थे GetRef()
लेवेन कीर्सेमेकर्स

1
स्पष्ट करने के लिए धन्यवाद, मुझे यकीन नहीं है कि आप उस tbh के बारे में क्या करने में सक्षम होने जा रहे हैं। सोचिए अगर किसी को पता हो, तो यह @ eric-lippert होगा क्योंकि उन्होंने VBScript बनाने वाली मूल टीम पर काम किया था।
लंकिमार्ट

2
मेरे पास आपके द्वारा 7 विंडोज पर KB4525236 या KB4524570 के बिना वर्णित व्यवहार है (जाहिर है कि एक और KB है जो इसे विंडोज 7 के लिए करता है)। फिर भी, VBScript में कोई कचरा संग्रह नहीं है, वस्तुओं को नष्ट कर दिया जाना चाहिए , जब उनकी संदर्भ संख्या शून्य हो जाती है। यदि ऐसा नहीं होता है, तो यह GC कामकाज के एक अलग तरीके के बजाय एक इंजन बग है।
11

2
यह स्पष्ट चर के बिना भी मामला है। दो With New IDummyInstance : End Withब्लॉक अभी भी "इनिशियलाइज़ फर्स्ट इंस्टेंस, इनिशियलाइज़ सेकंड इंस्टेंस, टर्मिनेट फ़र्स्ट इंस्टेंस, टर्मिनेट सेकंड इंस्टेंस" का उत्पादन करते हैं। यह बहुत गलत है, इसकी सूचना दी जानी चाहिए। इसके अलावा स्मृति खपत बात से, यह पूरी तरह से टूट जाता है यह
GSerg

1
@GSerg - क्या आपको यह रिपोर्ट करने के लिए एक चैनल होना चाहिए? कुछ भी नहीं मुझे तेजी से पता लगाने की कोशिश कर रहा है जहां मुद्दों की रिपोर्ट करने के लिए। इस सहायता पृष्ठ के लिए उदाहरण होता है के लिए इस सहायता पृष्ठ जो प्रभावी रूप से कुछ भी नहीं होता है।
लेवेन कीर्सेमेकर्स

जवाबों:


1

चूंकि मेरे पास कोई समाधान या आधिकारिक स्रोत नहीं है जो इस मुद्दे की व्याख्या करता है कि मैं बाउंटी के अवसान की प्रतीक्षा कर रहा था।

मैं एक अप्रिय बदलाव के साथ आया हूं जो बग ठीक होने तक मदद कर सकता है।

वर्कअराउंड किसी भी स्थानीय वैरिएबल का उपयोग ऑब्जेक्ट इंस्टेंस को उन प्रक्रियाओं में रखने के लिए नहीं है, जिनके माध्यम से निष्पादित किया जा सकता है GetRef

किसी स्थानीय (या वैश्विक यदि कोई पुनरावृत्ति नहीं है) का उपयोग करके निहित या स्पष्ट चर के बजाय, वस्तु उदाहरणों को धारण करने के लिए शब्दकोश वस्तु है और उन्हें उस शब्दकोश के माध्यम से कॉल करना है।

Sub CreateDestroyTwoInstances
  Dim Refs
  Set Refs = CreateObject("Scripting.Dictionary")
  Name = "First Instance"
  Refs.Add "DummyInstance", New IDummyInstance
  ' Call Refs("DummyInstance").DoSomething()
  Refs.Remove "DummyInstance"
  Name = "Second Instance"
  Refs.Add "DummyInstance", New IDummyInstance
  ' Call Refs("DummyInstance").DoSomething()
  Refs.Remove "DummyInstance"
End Sub

यदि आपके पास एक स्क्रिप्ट है जो बहुत जटिल नहीं है, तो इसका उपयोग करना उचित लगता है।


1
बस इसका परीक्षण किया है और मैं पुष्टि कर सकता हूं कि यह मेरी मशीन पर काम करता है। मैं इसे समाधान के रूप में चिह्नित करने जा रहा हूं। यह तब तक सबसे अच्छा है जब तक कि Microsoft एक सुधार प्रदान नहीं करता (यह मानते हुए कि वे इसे बग मानते हैं)
लेवेन कीर्सेमेकर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.