আইফিশারক্লাসে মেমরি ফাঁসকে সম্বোধন করছেন? আরকঅবজেক্টসের সন্ধান (কেবল এসডিইতে সরাসরি সংযোগ সহ)?


16

ইএসআরআই সমর্থন বলছে যে তারা বিষয়টি পুনরুত্পাদন করেছে এবং একটি বাগ রিপোর্ট (NIM070156) খুলেছে।

আমি স্থির করেছি একটি মেমরি লিক (অপরিচালিত গাদা মেমরি) যে যে ঘটে যখন একটি টুল আমার .NET / C # এর ArcMap অ্যাড-মধ্যে সঞ্চালিত একটি স্থানিক ক্যোয়ারী (একটি ফিরে ICursorথেকে IFeatureClass.Searchএকটি সঙ্গে ISpatialFilterক্যোয়ারী ফিল্টার)। সমস্ত COM অবজেক্টগুলি আর প্রয়োজনের সাথে সাথে ব্যবহার করা হবে না (ব্যবহার করা Marshal.FinalReleaseCOMObject)।

এটি নির্ধারণ করার জন্য আমি প্রথমে আরক্যাপ্যাপেক্সের ব্যক্তিগত বাইটস, ভার্চুয়াল বাইটস এবং ওয়ার্কিং সেটগুলির জন্য কাউন্টারগুলির সাথে একটি পারফরমন সেশন সেট আপ করেছি এবং উল্লেখ করেছি যে এই তিনটিই ক্রমটি সম্পাদন করে এমন সরঞ্জামের প্রতিটি ব্যবহারের সাথে ধীরে ধীরে বৃদ্ধি পেয়েছে (মোটামুটি 500KB দ্বারা) । গুরুতরভাবে, এটি কেবল তখন ঘটে যখন এসডিইতে সরাসরি সংযোগ (ST_Geometry স্টোরেজ, ওরাকল 11g ক্লায়েন্ট এবং সার্ভার) ব্যবহার করে বৈশিষ্ট্য ক্লাসের বিরুদ্ধে সঞ্চালিত হয় । কোনও ফাইল জিওডাটাবেস ব্যবহার করার সাথে সাথে অ্যাপ্লিকেশন সংযোগ ব্যবহার করে এমন কোনও পুরানো এসডিই উদাহরণের সাথে সংযোগ করার সময় কাউন্টারগুলি স্থির থাকে remained

তারপরে আমি লিকডিয়াগ এবং এলডিগ্রাফার (এই ব্লগ পোস্টের কিছু গাইডেন্স সহ ) ব্যবহার করেছি এবং তিনবার উইন্ডোজ হিপ অ্যালোকেটর লগড করেছি: যখন আমি প্রথম আর্কম্যাপটি লোড করি এবং এটি আরম্ভ করার জন্য সরঞ্জামটি নির্বাচন করি, তখন সরঞ্জামটি কয়েক ডজন বার চালানোর পরে এবং চলার পরে এটি আরও কয়েক ডজন বার।

এলডিগ্রাফারের ডিফল্ট ভিউ (মোট আকার) এ প্রদর্শিত ফলাফল এখানে রয়েছে: এলডিগ্রাফার গ্রাফ মেমরির ব্যবহারের ক্ষেত্রে অবিচ্ছিন্ন বৃদ্ধি দেখায়

লাল রেখার জন্য এখানে কল স্ট্যাক রয়েছে: SgsShapeFindRelation2 ফাংশনে এস.জি.এল.এল কল দেখানো কল স্ট্যাক

আপনি যেমন SgsShapeFindRelation2এস.জে.ডি.এল-তে ফাংশনটি দেখতে পাচ্ছেন তা মেমরি ফুটোটির জন্য দায়ী বলে মনে হয়।

আমি যেমন বুঝতে পারি যে এস.জি.ডিএল হ'ল আর্কওবজেক্টস দ্বারা ব্যবহৃত মূল জ্যামিতি গ্রন্থাগার, এবং SgsShapeFindRelation2সম্ভবত সেখানে স্থানিক ফিল্টার প্রয়োগ করা হচ্ছে।

আমি অন্য কিছু করার আগে, আমি কেবল দেখতে চেয়েছিলাম যে অন্য কেউ এই ইস্যুতে (বা অনুরূপ কিছু) চালিত হয়েছে কিনা এবং তারা যদি এ সম্পর্কে কিছু করতে সক্ষম হয় তবে কী হবে। এছাড়াও কেবল সরাসরি সংযোগের ফলেই এর কারণ কী হতে পারে? এই শব্দটি কি আরকোবজেক্টস, একটি কনফিগারেশন সমস্যা, বা কোনও প্রোগ্রামিং সমস্যার মতো বাগের মতো?

এই আচরণটি উত্পাদন করে এমন পদ্ধতির নূন্যতম সংস্করণ এখানে রয়েছে:

private string GetValueAtPoint(IPoint pPoint, IFeatureClass pFeatureClass, string pFieldName)
{
    string results = "";
    ISpatialFilter pSpatialFilter = null;
    ICursor pCursor = null;
    IRow pRow = null;
    try
    {
        pSpatialFilter = new SpatialFilterClass();
        pSpatialFilter.Geometry = pPoint;
        pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName;
        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
        pSpatialFilter.SearchOrder = esriSearchOrder.esriSearchOrderSpatial;
        pCursor = (ICursor)pFeatureClass.Search(pSpatialFilter, false);
        pRow = pCursor.NextRow();
        if (pRow != null)
            results = pRow.get_Value(pFeatureClass.FindField(pFieldName)).ToString();
    }
    finally
    {
        // Explicitly release COM objects
        if (pRow != null)
            Marshal.FinalReleaseComObject(pRow);
        if (pCursor != null)
            Marshal.FinalReleaseComObject(pCursor);
        if (pSpatialFilter != null)
            Marshal.FinalReleaseComObject(pSpatialFilter);
    }
    return results;
}

এখানে রাগির সাথে নীচের আলোচনার ভিত্তিতে আমার কাজের কোডটি দেওয়া হল:

private bool PointIntersectsFeature(IPoint pPoint, IFeature pFeature)
{
    bool returnVal = false;
    ITopologicalOperator pTopoOp = null;
    IGeometry pGeom = null;
    try
    {
        pTopoOp = ((IClone)pPoint).Clone() as ITopologicalOperator;
        if (pTopoOp != null)
        {
            pGeom = pTopoOp.Intersect(pFeature.Shape, esriGeometryDimension.esriGeometry0Dimension);
            if (pGeom != null && !(pGeom.IsEmpty))
                returnVal = true;
        }
    }
    finally
    {
    // Explicitly release COM objects
        if (pGeom != null)
            Marshal.FinalReleaseComObject(pGeom);
        if (pTopoOp != null)
            Marshal.FinalReleaseComObject(pTopoOp);
    }
    return returnVal;
}

private string GetValueAtPoint(IPoint pPoint, IFeatureClass pFeatureClass, string pFieldName)
{
    string results = "";
    ISpatialFilter pSpatialFilter = null;
    IFeatureCursor pFeatureCursor = null;
    IFeature pFeature = null;
    try
    {
        pSpatialFilter = new SpatialFilterClass();
        pSpatialFilter.Geometry = pPoint;
        pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName;
        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelEnvelopeIntersects;
        pFeatureCursor = pFeatureClass.Search(pSpatialFilter, true);
        pFeature = pFeatureCursor.NextFeature();
        while (pFeature != null)
        {
            if (PointIntersectsFeature(pPoint, pFeature))
            {
                results = pFeature.get_Value(pFeatureClass.FindField(pFieldName)).ToString();
                break;
            }
            pFeature = pFeatureCursor.NextFeature();
        }
    }
    finally
    {
        // Explicitly release COM objects
        if (pFeature != null)
            Marshal.FinalReleaseComObject(pFeature);
        if (pFeatureCursor != null)
            Marshal.FinalReleaseComObject(pFeatureCursor);
        if (pSpatialFilter != null)
            Marshal.FinalReleaseComObject(pSpatialFilter);
    }
    return results;
}

1
+1 দুর্দান্ত বিশ্লেষণ। আপনি কি এটি সরাসরি প্রত্যক্ষ সংযোগ দিয়ে দেখছেন ?
কर्क কুইকেনডাল

এটি কেবলমাত্র কোনও পুরানো সার্ভারে পরীক্ষা করা হয়েছে যা অ্যাপ্লিকেশন সংযোগ ব্যবহার করে এবং সেখানে কোনও মেমরি ফাঁস হয় না। সরাসরি সংযোগ নির্দিষ্ট তাই নিশ্চিত!
blah238

আরকজিআইএস এর কোন সংস্করণ (পরিষেবা প্যাক স্তর সহ)?
ফিলিপ

ক্লায়েন্ট: আরকজিআইএস 10 এসপি 2, সার্ভার: আর্কজিআইএস 9.3.1 এসপি 1 (আমি মনে করি, আগামীকাল ডাবল চেক করবে)।
blah238

আপনার বিবেচনা করা উচিত এমন কোনও ওরাকল ড্রাইভার সংস্করণ নেই, এটি বেশ কিছুক্ষণ হয়ে গেছে তবে ODP.NET হতে পারে?
কर्क কুইকেনডাল

উত্তর:


6

এটি একটি বাগের মতো দেখাচ্ছে।

এসজিটিতে আরকএসডি জ্যামিতি গ্রন্থাগার রয়েছে এবং আরকোবজেক্টস জ্যামিতি লাইব্রেরি নয় ... পরীক্ষার জন্য অর্কবজেক্টস জ্যামিতি লাইব্রেরি হিট হওয়ার আগে এটি প্রাক ফিল্টার হিসাবে ব্যবহৃত হয়।

এটা চেষ্টা কর:

এই রেখা ছাড়ুন:

pSpatialFilter.SearchOrder = esriSearchOrder.esriSearchOrderSpatial;

এবং যেহেতু আপনি সারিটির কোনও রেফারেন্স সংরক্ষণ করছেন না, তাই আপনাকে পুনর্ব্যবহারকারী কার্সার ব্যবহার না করার প্রয়োজন নেই, সুতরাং মিথ্যা পতাকাটি সত্যে স্যুইচ করুন।

pCursor = (ICursor)pFeatureClass.Search(pSpatialFilter, true);

আপনার স্মৃতিশক্তি গ্রহণ এবং রানটাইম গতির উভয় ক্ষেত্রেই উন্নতি দেখতে হবে। তবুও, ত্রুটিটি এখনও আঘাত করা থাকলে, এটি আশাবাদী নাটকীয়ভাবে এটি বিলম্ব করবে :)


1
ধন্যবাদ @ রাগী - আমি উভয় পরিবর্তনের চেষ্টা করেছি কিন্তু মেমরি ফাঁস হওয়ার হারে কোনও পরিবর্তন হয়নি।
blah238

আপনি কি 2 স্তরের (সরাসরি সংযোগ) বনাম 3 স্তরের (অ্যাপ্লিকেশন সার্ভার) সংযোগ চেষ্টা করতে পারেন? আপনি যদি ইতিমধ্যে অ্যাপ্লিকেশন সার্ভারটি চালু রেখেছেন তবে এটি কেবল এসডি সংযোগের স্ট্রিংয়ে পরিবর্তন হওয়া উচিত।
রাগী ইয়াসের বুড়হুম

ওহ, স্রেফ কার্কের মন্তব্য দেখেছি, সুতরাং এটি সরাসরি সংযোগের বিষয়। আইএমএইচও, আপনি যদি এটি 3 টি স্তর দিয়ে করেন তবে সম্ভাব্যতা রয়েছে যে আপনি সার্ভারের পাশের লিকটি দেখতে পাবেন, কিন্তু ক্লায়েন্টটি একই রকম থাকবে। আমি জিজ্ঞাসা করতে পারি যে আপনি সম্পাদনাগুলি বা ক্লোনিং জ্যামিতিগুলি দিয়ে কিছু করছেন কিনা?
রাগী ইয়াছার বুড়হুম

1
ভাল, হ্যাঁ এবং না। 3 স্তরের মোড, জিওমগর আবাসিক থাকে এবং প্রতিটি সংযোগের জন্য এটি একটি নতুন জিএসআরভিআর প্রক্রিয়া তৈরি করে যা আপনার সংযোগ বিচ্ছিন্ন হওয়ার পরে মারা যাবে, সুতরাং যদি ফাঁসটি থাকে, এটি আপনার সংযোগ বিচ্ছিন্ন হওয়ার পরে এটি চলে যাবে। এছাড়াও, আমরা সরাসরি সংযোগের কিছুটা আলাদা কোড পাথের সত্যটিকে ছাড় দিতে পারি না ... দুটি জিনিস চেষ্টা করে দেখুন। এক, কেবল স্থানিক ফিল্টারটি সম্পূর্ণভাবে স্যুইচ করুন এবং প্রথম বৈশিষ্ট্যটি ফিরিয়ে দিন তারপরে কেবল এসরিস্পটিয়ালালেল ইনভেলপস চেষ্টা করুন। আমি জানি যে শব্দার্থগতভাবে এগুলির কোনওটিই এক নয়, তবে আমরা প্রথমে লিকটি ট্র্যাক করতে চাই।
রাগী ইয়াছার বুড়হুম

3
হ্যাঁ, তাই উভয় পদ্ধতিই স্যাজ শাপফাইন্ডআরলেশন 2 কলটি এড়িয়ে চলেছে। এখনই এটি ব্যবহার করে দেখুন, এসডিএসপিটিয়াললেল্প এনভেলপিকে স্পিডিয়াল ফিল্টারে সূক্ষ্ম সুপার বুনিয়াদী প্রাক-ফিল্টারিং করতে, এবং তারপরে আইটিপোলজিকাল অপারেটর :: ক্লায়েন্টের প্রকৃত পরীক্ষাটি করতে ছেদ করুন। এটি স্যাড শাপফাইন্ডআরলেশন 2 এর মতো দক্ষ নাও হতে পারে তবে এটি সেই ফাংশনটিকে আঘাত করা এড়াতে পারে এবং তাই ফুটোটি এড়াতে পারে।
রাগী ইয়াছার বুড়হুম

4

যদি এখনও কেউ এই বিষয়ে আগ্রহী হন তবে এটি সংস্করণ 10.1 এ স্থির করা হয়েছিল।

ইএসআরআই প্রযুক্তিগত সহায়তা নম্বর: NIM070156 এবং NIM062420

http://support.esri.com/en/bugs/nimbus/TklNMDcwMTU2 http://support.esri.com/en/bugs/nimbus/TklNMDYyNDIw


এটি সংস্করণ স্থির জন্য কিছু তালিকাবদ্ধ করে না তাই আমার ধারণা আমি এটির জন্য আপনার কথাটি নিতে হবে। যদিও আমি 10.1 এ পরীক্ষা করে দেখিনি। এছাড়াও আমার বাগ রিপোর্টে ইস্যুটির লেবেলিংয়ের সাথে কোনও সম্পর্ক নেই তাই তারা কেন এটিকে অন্য একটির সদৃশ হিসাবে চিহ্নিত করেছে তা নিশ্চিত নয়।
blah238

1

এর পরিবর্তে আপনি নিম্নলিখিত প্যাটার্নটি ব্যবহার করে দেখতে পারেন try / finally { Marshal.FinalReleaseComObject(...) }:

using (ESRI.ArcGIS.ADF.ComReleaser cr) {
    var cursor = (ICursor) fc.Search(...);
    cr.ManageLifetime(cursor);
    // ...
}

ডাইরেক্ট কানেক্টের সাথেও কাজ করছি, আমি System.GC.Collect()পর্যায়ক্রমে (প্রতিটি বহু পুনরুক্তি) জোর করে লুপগুলিতে কিছুটা সাফল্য পেয়েছি , তবে এটি দেখতে খারাপ লাগে।


আমি এখানে বর্ণিত কার্সারগুলি পুনর্ব্যবহারের জন্য জেমস ম্যাকের পদ্ধতিটি ব্যবহার করে কমরেইলজারকে একটি শট দিয়েছি : ফোরামস.কার্গিস.com / থ্রেডস / - - এটি কোনও পার্থক্য করেনি (এটি কেবল মার্শালকে মোড়ায়। রিলিজ কমোবজেক্ট যাইহোক, তাই খুব আশ্চর্যজনক নয়)। আমি জিসি.কলেক্ট ব্যবহার করার চেষ্টাও করেছি তবে এর কোনও প্রভাবও ছিল না। আমার উল্লেখ করা উচিত ছিল আমি .NET প্রোফাইলার দু'একটি ব্যবহার করে পরিচালিত মেমোরিটিও দেখেছিলাম এবং তাদের মধ্যে কোনওরই কোনও পরিচালিত অবজেক্ট বা ম্যানেজড মেমরি পাইলিং পাওয়া যায় নি, যাতে আমাকে নিয়ন্ত্রণহীন মেমোরিটি দেখার জন্য পরিচালিত করে।
blah238
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.