আপনি কি কখনও কোনও প্রকল্পে ফ্যান্টম রেফারেন্স ব্যবহার করেছেন?


90

আমি কেবল যে জিনিসটি সম্পর্কে জানি PhantomReferenceতা হ'ল

  • আপনি যদি এর get()পদ্ধতিটি ব্যবহার করেন তবে এটি সর্বদা ফিরে আসবে nullএবং না অবজেক্ট not এর ব্যবহার কী?
  • ব্যবহার করে PhantomReference, আপনি এটি নিশ্চিত করেছেন যে finalizeপদ্ধতিটি থেকে অবজেক্টটি পুনরুত্থিত করা যাবে না ।

তবে এই ধারণা / শ্রেণীর ব্যবহার কী?

আপনি কি কখনও আপনার প্রকল্পে এটি ব্যবহার করেছেন বা আমাদের যেখানে এটি ব্যবহার করা উচিত তার কোনও উদাহরণ রয়েছে?



যেহেতু আপনি কোনও ফ্যান্টম রেফারেন্সের রেফার করা আপত্তিটি পেতে পারেন না, এটির একটি সম্পূর্ণ ভুল নাম: এটি বলা উচিত ছিল FakeReferenceবা NonReference
পেসারিয়ার

এখানে কোড সহ anothre থ্রেড এর stackoverflow.com/q/43311825/632951
Pacerier

উত্তর:


47

আমি অবজেক্ট তৈরি এবং ধ্বংস নিরীক্ষণের জন্যPhantomReference একটি সরল, খুব বিশেষ ধরণের মেমরি প্রোফাইলার ব্যবহার করেছি। ধ্বংসের খোঁজ রাখা আমার তাদের দরকার ছিল। তবে পন্থাটি সেকেলে। (এটি 2004 সালে J2SE 1.4 লক্ষ্য করে লেখা হয়েছিল।) পেশাদার প্রোফাইলিং সরঞ্জামগুলি অনেক বেশি শক্তিশালী এবং নির্ভরযোগ্য এবং জেএমএক্স বা এজেন্টস এবং জেভিএমটিআই-র মতো নতুন জাভা 5 বৈশিষ্ট্যগুলিও এর জন্য ব্যবহার করা যেতে পারে।

PhantomReferenceগুলি (রেফারেন্সের সারির সাথে সর্বদা একসাথে ব্যবহৃত হয়) এর চেয়ে উচ্চতর finalizeযা কিছু সমস্যা আছে এবং তাই এড়ানো উচিত। মূলত বস্তুগুলি আবার অ্যাক্সেসযোগ্য making এটি চূড়ান্তকরণকারীর অভিভাবক প্রবাদ দিয়ে এড়ানো যেতে পারে (-> 'কার্যকর জাভা'তে আরও পড়ুন)। সুতরাং তারা নতুন চূড়ান্ত হয়

তদ্ব্যতীত, PhantomReferenceএস

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

এবং হিসাবে পিএসডি প্রথম লিখেছিলেন, Roedy সবুজ টি রেফারেন্সের ভাল সারসংক্ষেপ


21

জাভা গ্লোসারি থেকে একটি সাধারণ ডাইস-আপ টেবিলের ব্যাখ্যা

কোনটি অবশ্যই ফ্যান্টম রেফারেন্স ডকুমেন্টেশনের সাথে মিলে যায় :

ফ্যান্টম রেফারেন্স অবজেক্টস, যা সংগ্রাহক নির্ধারণের পরে উত্থাপিত হয় যে তাদের রেফারেন্টগুলি অন্যথায় পুনরুদ্ধার করা যেতে পারে। ফ্যান্টম রেফারেন্সগুলি প্রায়শই জাভা চূড়ান্তকরণ পদ্ধতিতে যতটা সম্ভব তার চেয়ে আরও নমনীয় উপায়ে প্রাক-মর্টেম ক্লিনআপ ক্রিয়াকলাপের জন্য ব্যবহৃত হয়।

এবং সর্বশেষে তবে সর্বনিম্ন নয়, সমস্ত বেহাল বিবরণ ( এটি একটি ভাল পঠিত ): জাভা রেফারেন্স অবজেক্টস (বা আমি কীভাবে উদ্বেগ বন্ধ করতে এবং আউটআফমিউরিওর ভালবাসতে শিখেছি)

শুভ কোডিং। (তবে প্রশ্নের উত্তর দেওয়ার জন্য, আমি কেবল কখনও WeakReferences ব্যবহার করেছি))


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

4
বাহ, কেডগ্রিগরি থেকে এই নিবন্ধটি একটি +10
প্যাসেরিয়ার

14

ফ্যান্টম রেফারেন্স ব্যবহারের দুর্দান্ত ব্যাখ্যা :

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


12

আমি একটি ব্যবহারিক এবং দরকারী ব্যবহারের সন্ধান পেয়েছি PhantomReferenceযার org.apache.commons.io.FileCleaningTrackerমধ্যে কমন্স-আইও প্রকল্পে রয়েছে। FileCleaningTrackerশারীরিক ফাইলটি মুছবে যখন এর চিহ্নিতকারী অবজেক্টটি আবর্জনা সংগ্রহ করা হয়।
খেয়াল করার মতো কিছু হ'ল Trackerক্লাস যা PhantomReferenceক্লাস প্রসারিত করে ।


5

এই জাভা 9 এর দ্বারা নিখুঁত হতে হবে! পরিবর্তে
ব্যবহার java.util.Cleanerকরুন! (বা sun.misc.Cleanerপুরানো জেআরই-তে)

মূল পোস্ট:


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

https://github.com/claudemartin/java-cleanup

কলব্যাকটি কীভাবে নিবন্ধিত হয়েছে তা দেখানোর জন্য এখানে একটি ছোট উদাহরণ রয়েছে:

  class Foo implements Cleanup {
    //...  
    public Foo() { 
    //...    
      this.registerCleanup((value) -> {
        try {
          // 'value' is 'this.resource'
          value.close();
        } catch (Exception e) {
          logger.warning("closing resource failed", e);
        }
      }, this.resource);
    }

এবং তারপরে উপরের মতো একই কাজ করে অটো-বন্ধ করার জন্য আরও সহজ পদ্ধতি রয়েছে:

this.registerAutoClose(this.resource);

আপনার প্রশ্নের উত্তর দিতে:

[তাহলে এর ব্যবহার কী]

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

তবে এই ধারণা / শ্রেণীর ব্যবহার কী?

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

আপনি কি কখনও আপনার প্রকল্পের কোনওটিতে এটি ব্যবহার করেছেন, অথবা আমাদের যেখানে এটি ব্যবহার করা উচিত তার কোনও উদাহরণ রয়েছে? অথবা এই ধারণাটি কেবলমাত্র সাক্ষাত্কারের দৃষ্টিভঙ্গির জন্য তৈরি করা হয়েছে;)

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


হ্যাঁ, ঠিক আমার সমাধান "জাভা-ক্লিনআপ" এর মতো। উভয়ই বিমূর্ততা, সুতরাং আপনার সরাসরি তাদের সাথে ডিল করার দরকার নেই।
ক্লড মার্টিন

3

পরীক্ষার অধীনে থাকা কোডটি কোনও অবজেক্টের জন্য অনিচ্ছাকৃত রেফারেন্স রাখে না তা যাচাই করতে আমি ইউনিট পরীক্ষায় ফ্যান্টম রেফারেন্স ব্যবহার করেছি। ( মূল কোড )

import static com.google.common.base.Preconditions.checkNotNull;
import static org.fest.assertions.Assertions.assertThat;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;

import com.google.common.testing.GcFinalization;

/**
* Helps to test for memory leaks
*/
public final class MemoryTester
{
private MemoryTester()
{
}

/**
* A simple {@link PhantomReference} that can be used to assert that all references to it is
* gone.
*/
public static final class FinalizationAwareObject extends PhantomReference<Object>
{
private final WeakReference<Object> weakReference;

private FinalizationAwareObject(Object referent, ReferenceQueue<Object> referenceQueue)
{
super(checkNotNull(referent), referenceQueue);
weakReference = new WeakReference<Object>(referent, referenceQueue);
}

/**
* Runs a full {@link System#gc() GC} and asserts that the reference has been released
* afterwards
*/
public void assertThatNoMoreReferencesToReferentIsKept()
{
String leakedObjectDescription = String.valueOf(weakReference.get());
GcFinalization.awaitFullGc();
assertThat(isEnqueued()).as("Object: " + leakedObjectDescription + " was leaked").isTrue();
}
}

/**
* Creates a {@link FinalizationAwareObject} that will know if {@code referenceToKeepTrackOff}
* has been garbage collected. Call
* {@link FinalizationAwareObject#assertThatNoMoreReferencesToReferentIsKept()} when you expect
* all references to {@code referenceToKeepTrackOff} be gone.
*/
public static FinalizationAwareObject createFinalizationAwareObject(Object referenceToKeepTrackOff)
{
return new FinalizationAwareObject(referenceToKeepTrackOff, new ReferenceQueue<Object>());
}
}

এবং পরীক্ষা :

@Test
public void testThatHoldingOnToAnObjectIsTreatedAsALeak() throws Exception
{
    Object holdMeTight = new String("Hold-me-tight");
    FinalizationAwareObject finalizationAwareObject = MemoryTester.createFinalizationAwareObject(holdMeTight);
    try
    {
    finalizationAwareObject.assertThatNoMoreReferencesToReferentIsKept();
    fail("holdMeTight was held but memory leak tester did not discover it");
    }
    catch(AssertionError expected)
    {
    assertThat(expected).hasMessage("[Object: Hold-me-tight was leaked] expected:<[tru]e> but was:<[fals]e>");
    }
}

2

WeakReferenceযেখানে PhantomReferenceবেশি উপযুক্ত সেখানে এটি ব্যবহার করা সাধারণ । WeakReferenceআবর্জনা সংগ্রহকারী কর্তৃক সাফ হয়ে যাওয়ার পরে / বস্তুগুলিকে পুনরুত্থিত করতে সক্ষম হওয়ার কিছু সমস্যা এড়ানো যায় certain সাধারণত পার্থক্যটি বিবেচনা করে না কারণ লোকেরা নির্বোধ ব্যাগার খেলছে না।

ব্যবহার PhantomReferenceকারণ আপনার সাজা দিতে পারে না যে একটি বিট আরো অনধিকারমূলক হতে থাকে getপদ্ধতি কাজ করে। আপনি উদাহরণস্বরূপ, লিখতে পারবেন না Phantom[Identity]HashMap


আইডেন্টিটি হ্যাশম্যাপ <ফ্যান্টম রেফারেন্স> আসলে একটি আইডেন্টিহ্যাশম্যাপের জন্য উপযুক্ত জায়গা। দৃ strong় রেফারেন্স নোট করুন ফ্যান্টম রেখেছিল, তবে রেফারেন্স নয়

আপনি কি আসলেই বোঝাতে চেয়েছেন যে দুর্বল রেফারেন্সগুলির জন্য, চূড়ান্ত করা আপত্তিটি পুনরায় তৈরি করতে পারে? weakref.getফিরে আসতে পারে null, এবং পরে, এটি এখনও আপত্তি ফিরে করতে সক্ষম?
পেসারিয়ার

@ পেসারিয়র finalizeএই বিষয়টিকে পুনরায় তৈরি করে না। এটি WeakReferenceপ্রত্যাবর্তনের পরে আবার বস্তুকে দৃ strongly়রূপে পৌঁছে দিতে পারেnull থেকেget এবং সজ্জিত ়রূপে পৌঁছনীয় করতে পারে। / (ইউজার 166390: যেমন একটি মানচিত্র রেফারেন্সের লক্ষ্য হিসাবে চিহ্নিত করা হয়েছে, যেমন সূত্রের WeakHashMapকোনও পরিচয়ের মানচিত্র নয় যা ভাল))
টম হাটিন -

1

যদি আপনি এর get () পদ্ধতি ব্যবহার করেন তবে এটি সর্বদা নালায় ফিরে আসবে, এবং অবজেক্টটি নয়। [তাহলে এর ব্যবহার কী]

কল করার দরকারী পদ্ধতিগুলি (পরিবর্তে get()) হবে isEnqueued()বা referenceQueue.remove()। আপনি এই পদক্ষেপগুলিকে কিছু পদক্ষেপ নেওয়ার জন্য কল করবেন যা অবজেক্টের আবর্জনা সংগ্রহের চূড়ান্ত পর্যায়ে সঞ্চালিত হওয়া দরকার।

প্রথমদিকে যখন অবজেক্টটির finalize()পদ্ধতিটি কল করা হয়, আপনি সেখানে ক্লোজিং হুকও রাখতে পারেন। তবে, অন্যরা যেমন বলেছে, সম্ভবত পরিষ্কার-পরিচ্ছন্নতা সম্পাদনের আরও কিছু নিশ্চিত উপায় রয়েছে বা আবর্জনা সংগ্রহের প্রাক ও পোস্ট পোস্ট করার পরে বা সাধারণভাবে অবজেক্টের জীবন শেষে।


1

আমি আরেকটি ব্যবহারিক প্রয়োগের পাওয়া PhantomReferencesমধ্যে LeakDetector জেটি বর্গ।

জেটি LeakDetectorক্লায়েন্ট কোডটি কোনও সংস্থান অর্জন করে কিনা তা সনাক্ত করতে LeakDetectorক্লাস ব্যবহার করে তবে কখনই এটি প্রকাশ করে না এবং ক্লাসটি PhantomReferencesএই উদ্দেশ্যে ব্যবহার করে ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.