Java.lang.String.intern () ব্যবহার করা কি ভাল অনুশীলন?


194

জাভাডোক সম্পর্কে String.intern()খুব বেশি বিশদ দেয় না। (সংক্ষেপে: এটি স্ট্রিংটির আধ্যাত্মিক উপস্থাপনা প্রদান করে, অভ্যন্তরীণ স্ট্রিংগুলি ব্যবহার করে তুলনা করার অনুমতি দেয় ==)

  • আমি কখন এই ফাংশনটির পক্ষে চাইব String.equals()?
  • জাভাডোকে কি পার্শ্ব প্রতিক্রিয়া উল্লেখ করা হয়নি, অর্থাৎ জেআইটি সংকলক দ্বারা কম-বেশি অপ্টিমাইজেশন রয়েছে?
  • এর আরও ব্যবহার আছে String.intern()কি?

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

হ্যাঁ, ইন্টার্নের () এর নিজস্ব কার্যকারিতা প্রভাব রয়েছে। বিশেষত কারণ ইন্টার্ন () ব্যয় আপনি ইন্টার্ন স্ট্রিংয়ের সাথে রৈখিকভাবে বৃদ্ধি পায় এবং সেগুলির একটি রেফারেন্স রাখেন। কমপক্ষে একটি সূর্য / ওরাকল 1.6.0_30 ভিএম এ।
lacroix1547

উত্তর:


125

আমি কখন স্ট্রিং.ইকুয়ালসের পক্ষে এই ফাংশনটি ব্যবহার করব ()

যখন আপনার গতির প্রয়োজন হয় আপনি রেফারেন্সের মাধ্যমে স্ট্রিংগুলি তুলনা করতে পারেন (== সমানর চেয়ে দ্রুত)

জাভাডোকের মধ্যে কি পার্শ্ব প্রতিক্রিয়া উল্লেখ করা হয়নি?

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

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

(জেগুরু থেকে)

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

(মাইকেল বর্গওয়ার্ট থেকে)


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

15
এএফআইএকের আরও নতুন ভিএমও আবর্জনা পার্মজেন স্থান সংগ্রহ করে।
ড্যানিয়েল রিকোভস্কি

31
ইন্টার্ন মেমরি পরিচালনা সম্পর্কে, তুলনার গতি নয়। মধ্যে পার্থক্য if (s1.equals(s2))এবং if (i1 == i2)ন্যূনতম যদি না আপনার একই নেতৃস্থানীয় অক্ষর দীর্ঘ স্ট্রিং অনেক আছে নেই। বেশিরভাগ বাস্তব-বিশ্বের ব্যবহারে (ইউআরএল ব্যতীত) প্রথম কয়েকটি অক্ষরের মধ্যে স্ট্রিংগুলি পৃথক হবে। এবং দীর্ঘ যদি-অন্য চেইনগুলি যাইহোক কোডের গন্ধ হয়: এনাম এবং ফান্টেক্টর মানচিত্র ব্যবহার করুন।
কেডগ্রিগরি

25
আপনি এখনও আপনার পুরো প্রোগ্রাম জুড়ে s1.equals সিনট্যাক্স ব্যবহার করতে পারেন, শর্ট সার্কিট মূল্যায়নের অভ্যন্তরীণভাবে == ব্যবহার করুন না, = সমাপ্তি ব্যবহার করতে পারেন
gtrak

15
মাইকেল বর্গওয়ার্ট বলেন নি যে অভ্যন্তরীণ স্ট্রিংগুলি আবর্জনা সংগ্রহ করা যাবে না। এবং এটি একটি মিথ্যা দাবী। মাইকের মন্তব্য (সঠিকভাবে) যা বলে তার চেয়ে সুক্ষ্ম।
স্টিফেন সি

193

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


4
এটা ঠিক না স্ট্রিংগুলির ইন্টার্নিং সর্বদা, স্বয়ংক্রিয়ভাবে ঘটে যখন প্রতিটি স্ট্রিং এক্সপ্রেশন মূল্যায়ন করা হয়। অক্ষরগুলির প্রতিটি অনন্য স্ট্রিংয়ের জন্য সর্বদা একটি অনুলিপি থাকে এবং যদি একাধিক ব্যবহার ঘটে তবে এটি "অভ্যন্তরীণভাবে ভাগ করা" হয়। স্ট্রিং.ইনটার্ন () কল করা এগুলি সমস্ত ঘটায় না - এটি কেবল অভ্যন্তরীণ প্রাসঙ্গিক প্রতিনিধিত্ব করে। জাভাদোক দেখুন।
গ্লেন সেরা

16
স্পষ্ট করে বলা দরকার - সংকলন-সময় ধ্রুব স্ট্রিংসের (আক্ষরিক এবং স্থির এক্সপ্রেশন) ইন্টার্নিং সর্বদা স্বয়ংক্রিয়ভাবে ঘটে। অতিরিক্তভাবে এটি ঘটে যখন স্ট্রিং.ইনটার্ন () রানটাইম গতিশীল মূল্যায়ন স্ট্রিংগুলিতে ডাকা হয়।
গ্লেন সেরা

সুতরাং আপনার অর্থ, যদি হিপগুলিতে "হ্যালো" এর 1000 টি অবজেক্ট থাকে এবং আমি তার একটিতে ইন্টার্ন () সঞ্চালন করি, তবে বাকী 999 বস্তু স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যাবে?
অরুণরাজ

অরুনরাজ না, আপনার 1000 টি এখনও স্তূপে থাকবে এবং ইন্টার্ন পুলে একটি অতিরিক্ত পরিমাণ থাকবে যা পরে str.intern()যখন পুনরায় ব্যবহারের জন্য প্রস্তুত হতে পারে । str"Hello"
ম্যাথিউউ

37

String.intern()আধুনিক জেভিএমগুলিতে সংগ্রহ করা আবশ্যক।
নিম্নলিখিত স্নাতকের স্মৃতিশক্তি নেই, জিসি ক্রিয়াকলাপের কারণে:

// java -cp . -Xmx128m UserOfIntern

public class UserOfIntern {
    public static void main(String[] args) {
        Random random = new Random();
        System.out.println(random.nextLong());
        while (true) {
            String s = String.valueOf(random.nextLong());
            s = s.intern();
        }
    }
}

নন জিসিড স্ট্রিং.ইনটার্ন () এর কল্পকাহিনীটিতে আরও (আমার কাছ থেকে ) দেখুন


26
OutOfMemoryException- না, আমার মস্তিষ্কে উপরের কোডটি নয়, জাভাটার্নিং নিবন্ধের লিঙ্ক, যা এই নিবন্ধের দিকে ইঙ্গিত করছে, যা জাভাটার্নিং নিবন্ধের দিকে ইঙ্গিত করছে, যা ... :-)
ব্যবহারকারী 85421

যদিও আপনি দেখতে পাচ্ছেন যে লিঙ্কটি যুক্ত করতে পোস্টটি সম্পাদিত হয়েছিল;)
রিকিং

3
আপনি উল্লেখ করতে পারেন যে আপনি যে বাহ্যিক রেফারেন্সের সাথে লিঙ্ক করেছেন তিনিও লেখক।
থরবজর্ন রাভন অ্যান্ডারসন

11
@ কার্লোস একটি বহিরাগত রেফারেন্সের সাথে সংযোগ স্থাপন করেছেন যা স্ট্যাকওভারফ্লোতে ফিরে লিঙ্কগুলি একটি কারণ হতে হবে .. স্ট্যাকওভারফ্লো :)
Seiti

2
@ সীতির বিজ্ঞপ্তি উল্লেখগুলি আজকাল সহজেই সনাক্ত করা যায়: পি
অজয়

16

আমি সম্প্রতি জাভা 6, 7 এবং 8 এ স্ট্রিং.ইনটার্ন () বাস্তবায়ন সম্পর্কে একটি নিবন্ধ লিখেছি: জাভা 6, 7 এবং 8 - স্ট্রিং পুলিংয়ে স্ট্রিং.ইনটার্ন

আমি আশা করি এটিতে জাভাতে স্ট্রিং পুলিংয়ের সাথে বর্তমান পরিস্থিতির সম্পর্কে পর্যাপ্ত তথ্য থাকতে হবে।

সংক্ষেপে:

  • String.intern()জাভা 6 এ এড়িয়ে চলুন , কারণ এটি পারমজেনে যায় into
  • String.intern()জাভা 7 এবং জাভা 8 এ পছন্দ করুন : এটি আপনার নিজের অবজেক্ট পুলের ঘূর্ণায়মানের চেয়ে 4-5x কম মেমরি ব্যবহার করে
  • টিউন করতে ভুলবেন না -XX:StringTableSize(ডিফল্ট সম্ভবত খুব ছোট; একটি প্রাথমিক সংখ্যা সেট করুন)

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

3
@ Mik1 লেখার জন্য ধন্যবাদ! অত্যন্ত তথ্যবহুল, পরিষ্কার এবং আপ টু ডেট নিবন্ধ। (আমি নিজেই এটির একটি লিঙ্ক পোস্ট করার উদ্দেশ্যে এখানে ফিরে এসেছি))
লূক উশারউড

1
-XX আরগ উল্লেখ করার জন্য ধন্যবাদ। আপনি টেবিলের পরিসংখ্যান দেখতে এটি ব্যবহার করতে পারেন: -এক্সএক্স: + প্রিন্টস্ট্রিং টেবিলস্ট্যাটিসটিক্স
ক্যাসাদলার

13

== এর সাথে স্ট্রিং তুলনা করা সমান () এর সাথে তুলনায় অনেক দ্রুত

৫ সময় দ্রুত, তবে যেহেতু স্ট্রিংয়ের তুলনা সাধারণত একটি প্রয়োগের মোট কার্যকরকরণ সময়ের কেবলমাত্র একটি সামান্য শতাংশের প্রতিনিধিত্ব করে, সামগ্রিক লাভ তার চেয়ে অনেক কম এবং চূড়ান্ত লাভটি কয়েক শতাংশে মিশ্রিত হবে।

স্ট্রিং.ইনটার্ন () স্ট্রিংটি হিপ থেকে দূরে টানুন এবং এটিকে পারমজেনে রাখুন

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

স্ট্রিং.ইন্টার্ন () স্ট্রিংগুলি আবর্জনা সংগ্রহ করা হয়

জেভিএমের নতুন সংস্করণগুলিতে অভ্যন্তরীণ স্ট্রিংগুলি আবর্জনা সংগ্রহ করা হয় যখন কোনও বস্তুর দ্বারা রেফারেন্স না দেওয়া হয়।

উপরের তিনটি বিষয়টিকে মাথায় রেখে আপনি স্ট্রিং ইন্টার্ন () কেবলমাত্র কিছু ক্ষেত্রে কার্যকর হতে পারে যখন আপনি প্রচুর স্ট্রিং তুলনা করেন, তবে আপনি ঠিক কী না জানেন তা অভ্যন্তরীণ স্ট্রিং ব্যবহার না করা ভাল you করছে ...



1
কেবল যোগ করার জন্য, হ্যাপ মেমরি ব্যতিক্রমগুলি কখনও কখনও পুনরুদ্ধার করা যায়, বিশেষত ওয়েব অ্যাপ্লিকেশনগুলির মতো থ্রেডযুক্ত মডেলগুলিতে। যখন পার্জেন নিঃশেষ হয়ে যায়, তখন কোনও অ্যাপ্লিকেশন সাধারণত স্থায়ীভাবে অ-কার্যকরী হয়ে যায় এবং প্রায়শই হত্যা না হওয়া পর্যন্ত থ্রেশ সংস্থান করে।
টেলর

7

আমি কখন স্ট্রিং.ইকুয়ালসের পক্ষে এই ফাংশনটি ব্যবহার করব ()

প্রদত্ত তারা বিভিন্ন জিনিস, সম্ভবত কখনও না।

পারফরম্যান্স কারণে স্ট্রিংগুলি অন্তর্ভুক্ত করা যাতে আপনি তাদের সাথে রেফারেন্সের সমতার জন্য তুলনা করতে পারেন কেবল তখনই উপকার হবে যদি আপনি কিছুক্ষণের জন্য স্ট্রিংয়ের রেফারেন্স রাখেন - ব্যবহারকারী ইনপুট থেকে আসা স্ট্রিংগুলি ইন্টার্ন করা হবে না।

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

UserIdইন্টার্নযুক্ত একটি টাইপ তৈরি করা প্রায় সর্বদা ভাল (কোনও থ্রিড-সেফ জেনেরিক ইন্টার্নিং মেকানিজম তৈরি করা সহজ) এবং কোনও ওপেন এনামের মতো কাজ করে, java.lang.Stringযদি কোনও ইউজার আইডি হয়ে থাকে তবে রেফারেন্স সিঁটমিকের সাথে টাইপটি ওভারলোড না করে ।

এইভাবে আপনি কোনও নির্দিষ্ট স্ট্রিংকে অন্তর্ভুক্ত করা হয়েছে কিনা তার মধ্যে আপনি বিভ্রান্তি বোধ করবেন না এবং আপনি উন্মুক্ত এনামে আপনার প্রয়োজনীয় কোনও অতিরিক্ত আচরণ সজ্জিত করতে পারবেন।


6

কোনও সুবিধা সম্পর্কে আমি অবগত নই এবং যদি কারওর মধ্যে থাকে তবে তারা ভাবতে পারে যে সমান () নিজেই অভ্যন্তরীণভাবে () এটি অভ্যন্তরীণভাবে ব্যবহার করবে (যা এটি করে না)।

বুথিং ইন্টার্ন () পুরাণ


7
আপনি বলছেন যে আপনি কোনও সুবিধা সম্পর্কে অবগত নন, আপনার পোস্টযুক্ত লিঙ্কটি তুলনাটি == 5x দ্রুত হিসাবে পাঠ্যকেন্দ্রিক পারফরম্যান্ট কোডের জন্য গুরুত্বপূর্ণ হিসাবে চিহ্নিত করে
ব্রায়ান অগ্নিউ

3
যখন আপনার কাছে পাঠ্য-তুলনা করার প্রচুর পরিমাণ রয়েছে তখন শেষ পর্যন্ত পার্মজেনের স্থানটি চলে যাবে। গতির পার্থক্য করার জন্য যখন খুব বেশি পাঠ্য-তুলনা হয় না তখন কিছু যায় আসে না। যেভাবেই হোক, কেবল আপনার স্ট্রিংগুলিকে ইন্টার্ন () করবেন না। এটা মূল্য নয়।
বোম্বে

এটি আরও বলতে থাকে যে সামগ্রিকভাবে আপেক্ষিক লাভটি সাধারণত ছোট হতে চলেছে।
বস্তু

আমি মনে করি না যে এ জাতীয় যুক্তি বৈধ is ভাল লিঙ্ক যদিও!
ড্যানিয়েল রিকোভস্কি

1
@ ডিআর: কি যুক্তি? এটি একটি বড় ভ্রান্তি। @ অবজেক্টস: দুঃখিত তবে আপনার যুক্তিগুলির কারণে অভাব হয়। ব্যবহারের জন্য খুব ভাল কারণ রয়েছে internএবং খুব ভাল কারণগুলি equalsডিফল্টরূপে এটি করে না। আপনার পোস্ট করা লিঙ্কটি সম্পূর্ণ বোলক ocks শেষ অনুচ্ছেদে এমনকি স্বীকার করা হয়েছে যে internএকটি বৈধ ব্যবহারের দৃশ্য রয়েছে: ভারি পাঠ্য প্রক্রিয়াকরণ (যেমন পার্সার)। "[এক্সওয়াইজেড] আপনি কী করছেন তা যদি আপনি জানেন না" তবে অবশেষে বিপজ্জনক যে এটি শারীরিকভাবে ব্যথা করে।
কনরাড রুডলফ

4

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

জাভা 7-তে, অভ্যন্তরীণ স্ট্রিংগুলি পারমজেনে বেশি দিন বাঁচে না বরং পরিবর্তে apগল হয়। সুতরাং আপনাকে এর আকার সম্পর্কে চিন্তা করার দরকার নেই এবং হ্যাঁ এটি আবর্জনা সংগ্রহ করে:

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


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

4

জাভাডোকে কি পার্শ্ব প্রতিক্রিয়া উল্লেখ করা হয়নি, অর্থাৎ জেআইটি সংকলক দ্বারা কম-বেশি অপ্টিমাইজেশন রয়েছে?

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

JVMS

জেভিএমএস 7 5.1 বলেছেন :

স্ট্রিং আক্ষরিক একটি ক্লাস স্ট্রিংয়ের উদাহরণের জন্য একটি উল্লেখ, এবং এটি একটি শ্রেণি বা ইন্টারফেসের বাইনারি উপস্থাপনায় একটি CONSTANT_String_info কাঠামো (.44.4.3) থেকে প্রাপ্ত। CONSTANT_String_info কাঠামোটি ইউনিকোড কোড পয়েন্টগুলির ক্রম দেয় যা স্ট্রিংকে আক্ষরিক গঠন করে।

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

("a" + "b" + "c").intern() == "abc"

একটি স্ট্রিং আক্ষরিক পেতে, জাভা ভার্চুয়াল মেশিন CONSTANT_String_info কাঠামো দ্বারা প্রদত্ত কোড পয়েন্টগুলির ক্রম পরীক্ষা করে।

  • যদি স্ট্রিং.ইনটার্ন মেথডটি পূর্বে ইউনিকোড কোড পয়েন্টের ক্রমযুক্ত স্ট্রিংয়ের উদাহরণ হিসাবে ডাকা হত যা CONSTANT_String_info কাঠামোর অনুরূপ, তবে স্ট্রিং আক্ষরিক ডেরিভেশন ফলাফল স্ট্রিংয়ের একই উদাহরণের একটি রেফারেন্স।

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

বাইটকোড

ওপেনজেডকে 7-তে বাইটোকোড বাস্তবায়ন দেখার জন্য এটিও শিক্ষণীয়।

যদি আমরা পচন করি:

public class StringPool {
    public static void main(String[] args) {
        String a = "abc";
        String b = "abc";
        String c = new String("abc");
        System.out.println(a);
        System.out.println(b);
        System.out.println(a == c);
    }
}

আমাদের ধ্রুবক পুলটিতে রয়েছে:

#2 = String             #32   // abc
[...]
#32 = Utf8               abc

এবং main:

 0: ldc           #2          // String abc
 2: astore_1
 3: ldc           #2          // String abc
 5: astore_2
 6: new           #3          // class java/lang/String
 9: dup
10: ldc           #2          // String abc
12: invokespecial #4          // Method java/lang/String."<init>":(Ljava/lang/String;)V
15: astore_3
16: getstatic     #5          // Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: invokevirtual #6          // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: getstatic     #5          // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: invokevirtual #6          // Method java/io/PrintStream.println:(Ljava/lang/String;)V
30: getstatic     #5          // Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_1
34: aload_3
35: if_acmpne     42
38: iconst_1
39: goto          43
42: iconst_0
43: invokevirtual #7          // Method java/io/PrintStream.println:(Z)V

কিভাবে নোট করুন:

  • 0এবং 3: একই ldc #2ধ্রুবক লোড করা হয় (আক্ষরিক)
  • 12: একটি নতুন স্ট্রিং উদাহরণ তৈরি করা হয়েছে ( #2যুক্তি হিসাবে)
  • 35: aএবং cএর সাথে নিয়মিত বস্তু হিসাবে তুলনা করা হয়if_acmpne

ধ্রুবক স্ট্রিংগুলির উপস্থাপনা বাইটকোডে বেশ জাদুযুক্ত:

এবং উপরের জেভিএমএসের উদ্ধৃতিটি বলে মনে হচ্ছে যে যখনই ইউটিএফ 8 একই হয়, তখন অভিন্ন উদাহরণগুলি লোড হয় ldc

আমি ক্ষেত্রগুলির জন্য একই রকম পরীক্ষা করেছি এবং:

  • static final String s = "abc"কনস্ট্যান্টভ্যালু অ্যাট্রিবিউটের মাধ্যমে ধ্রুবক টেবিলের দিকে নির্দেশ করে
  • চূড়ান্ত নয় এমন ক্ষেত্রগুলিতে সেই বৈশিষ্ট্য নেই, তবে এটি দিয়ে এখনও আরম্ভ করা যেতে পারে ldc

বোনাস : এটি ইন্টিজার পুলের সাথে তুলনা করুন , যার সরাসরি বাইটকোড সমর্থন নেই (যেমন কোনও CONSTANT_String_infoএনালগ নেই)।


2

আমি ইন্টার্ন এবং == - তুলনা কেবলমাত্র সমান-তুলনায় স্ট্রিংয়ের একাধিক তুলনায় বাধা হবার ক্ষেত্রে সমান পরিবর্তনের তুলনায় examine এটি অল্প সংখ্যক তুলনায় সাহায্য করার পক্ষে অত্যন্ত সম্ভাবনা নেই, কারণ ইন্টার্ন () নিখরচায় নয়। আক্রমণাত্মকভাবে স্ট্রিংগুলি ইন্টার্ন করার পরে আপনি ইন্টার্নে কলগুলি পেতে পারেন () ধীর এবং ধীর হয়ে উঠছে।


2

subString()উত্সের স্ট্রিংয়ের তুলনায় ফলাফল যখন ছোট হয় এবং অবজেক্টটির দীর্ঘ জীবন হয় তখন এক ধরণের মেমরি ফুটো এর ব্যবহার থেকে আসতে পারে।

সাধারণ সমাধানটি ব্যবহার করা হয় new String( s.subString(...))তবে যখন আপনার কোনও ক্লাস থাকে যা কোনও সম্ভাবনা / সম্ভাবনার ফলাফল সংরক্ষণ subString(...)করে এবং কলারের উপর কোনও নিয়ন্ত্রণ রাখে না, আপনি intern()স্ট্রিং আর্গুমেন্টগুলি কনস্ট্রাক্টরের কাছে জমা দেওয়ার বিষয়ে বিবেচনা করতে পারেন। এটি সম্ভাব্য বড় বাফার প্রকাশ করে।


আকর্ষণীয়, তবে সম্ভবত এটি বাস্তবায়ন নির্ভর।
অ্যাকোস্টাডিনভ

1
উপরে উল্লিখিত সম্ভাব্য মেমরি ফুটো জাভা 1.8 এবং 1.7.06 তে ঘটে না (এবং আরও নতুন) জাভা ১.7.০.০66 এ স্ট্রিংয়ের অভ্যন্তরীণ প্রতিনিধিত্বের পরিবর্তনগুলি দেখুন ।
এরেমেল

এটি নিশ্চিত করে যে কোনও কর্মক্ষমতা এবং / অথবা মেমরি প্রোফাইলিংয়ের পরে প্রয়োজনীয় হলে মাইক্রো-অপ্টিমাইজেশানগুলি প্রয়োগ করতে হবে। ধন্যবাদ.
akostadinov

2

স্ট্রিং ইন্টার্নিং সেই ক্ষেত্রে কার্যকর হয় যেখানে equals()পদ্ধতিটি প্রায়শই আহ্বান করা হয় কারণ equals()পদ্ধতিটি শুরুর দিকে অবজেক্টগুলি একই কিনা তা পরীক্ষা করার জন্য পদ্ধতিটি দ্রুত পরীক্ষা করে।

if (this == anObject) {
    return true;
}

এটি সাধারণত তখন ঘটে যখন Collectionকোনও কোডের মাধ্যমে অনুসন্ধান করা স্ট্রিং সমতা পরীক্ষা করতে পারে।

ইন্টার্নিংয়ের সাথে ব্যয় রয়েছে যদিও আমি কিছু কোডের একটি মাইক্রোব্যাঙ্কমার্ক সম্পাদন করেছি এবং খুঁজে পেয়েছি যে ইন্টার্নিং প্রক্রিয়াটি 10 ​​এর ফ্যাক্টর দ্বারা রানটাইম বৃদ্ধি করে।

ইন্টার্নিংয়ের সর্বোত্তম জায়গাটি সাধারণত আপনি যখন কোডের স্ট্রিংগুলি স্বয়ংক্রিয়ভাবে অভ্যন্তরীণ হয়ে থাকেন তখন কোডের বাইরে সংরক্ষণ করা কীগুলি পড়ে থাকেন। এটি প্রথমে আপনার ব্যবহারকারীর জরিমানা রোধ করার জন্য আপনার অ্যাপ্লিকেশনটির প্রাথমিক পর্যায়ে ঘটবে।

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

এ ছাড়া, বাকী কোডটিতে ইন্টার্নিং করার মতো খুব বেশি কিছু নেই কারণ এটি সাধারণত কোনও সুবিধা দেয় না।


1

আমি এটির ভরণপোষণের ঝামেলা না করে ভোট দিই।

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


1

http://kohlerm.blogspot.co.uk/2009/01/is-javalangstringintern-really-evil.html

অনুযায়ী পূর্বে বস্তুর তুলনা করতে String.equals()ব্যবহার করে এমন জোর দেয়"=="String

http://www.codeinstructions.com/2009/01/busting-javalangstringintern-myths.html

এটি স্ট্রিংগুলির দৈর্ঘ্য এবং তারপরে সামগ্রীগুলির সাথে তুলনা করে।

(যাইহোক, বিক্রয় ক্যাটালগের পণ্য কোড স্ট্রিংগুলি একই দৈর্ঘ্যের হিসাবে দায়বদ্ধ - বিআইসিসি 0417 একজন সাইক্লিস্টের সুরক্ষা হেলমেট, টিআইজি 20003 একটি জীবিত প্রাপ্তবয়স্ক পুরুষ বাঘ - এর মধ্যে একটি অর্ডার করার জন্য আপনার সম্ভবত সমস্ত ধরণের লাইসেন্সের প্রয়োজন need সম্ভবত আপনি একই সাথে একটি সুরক্ষার হেলমেট অর্ডার করুন))

সুতরাং এটি আপনার স্ট্রিংগুলির intern()সংস্করণগুলির সাথে প্রতিস্থাপন করে কোনও উপকার পেয়েছে বলে মনে হচ্ছে তবে আপনি equals()আপনার প্রোগ্রামিংয়ের জন্য "==" ব্যবহার করে সুরক্ষা - এবং পঠনযোগ্যতা এবং মান সম্মতি - ছাড়াই পাবেন get এবং আমি যা বলতে যাচ্ছি তার বেশিরভাগ নির্ভর করে এটি সত্য হওয়া, যদি এটি সত্য হয়।

কিন্তু আপনি কি String.equals()পরীক্ষার আগে এটি ব্যবহারের আগে একটি স্ট্রিং পাস করেছেন এবং অন্য কোনও বস্তু নয় "=="? আমি বলার যোগ্য নই, তবে আমি অনুমান করব না, কারণ অপ্রতিরোধ্যভাবে বেশিরভাগ equals()অপারেশনগুলি স্ট্রিং থেকে স্ট্রিংয়ের কাজ হবে, সুতরাং সেই পরীক্ষাটি প্রায় সর্বদা পাস করা হয়। প্রকৃতপক্ষে, "==" এর ভিতরে অগ্রাধিকার দেওয়া String.equals()একটি আত্মবিশ্বাসকে বোঝায় যে আপনি প্রায়শই স্ট্রিংকে একই প্রকৃত বস্তুর সাথে তুলনা করছেন।

আমি আশা করি যে নিম্নোক্ত রেখাগুলি "মিথ্যা" ফলাফলের ফলে কারও অবাক না হয়ে:

    Integer i = 1;
    System.out.println("1".equals(i));

কিন্তু যদি আপনি পরিবর্তন iকরতে i.toString()দ্বিতীয় লাইন, অবশ্যই এটা true

আপনি যে জায়গাগুলিতে ইন্টার্নিংয়ের মাধ্যমে কোনও সুবিধার জন্য আশা করতে পারেন সেগুলি অন্তর্ভুক্ত রয়েছে Setএবং Mapস্পষ্টতই। আমি আশা করি যে ইন্টার্নযুক্ত স্ট্রিংগুলিতে তাদের হ্যাশকোডগুলি ক্যাশেড রয়েছে ... আমি মনে করি এটির প্রয়োজন হবে। এবং আমি আশা করি যে আমি আমার কাছে এক মিলিয়ন ডলার উপার্জন করতে পারে এমন ধারণাটি সরিয়ে নেই। :-)

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

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

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


0

ইন্টার্ন ব্যবহারের আসল কারণটি উপরেরটি নয়। আপনি স্মৃতি থেকে সরে যাওয়ার পরে এটি ব্যবহার করতে পারেন। সাধারণ প্রোগ্রামে প্রচুর স্ট্রিং হ'ল স্ট্রিং.সুবস্ট্রিং () অন্যান্য বড় স্ট্রিংয়ের [একটি 100 কে এক্সএমএল ফাইল থেকে কোনও ব্যবহারকারী-নাম নেওয়ার কথা ভাবুন। জাভা বাস্তবায়ন হ'ল, স্ট্রিংগুলিতে মূল স্ট্রিং এবং সেই বিশাল স্ট্রিংয়ের শুরু + সমাপ্তির একটি রেফারেন্স রয়েছে। (এর পিছনে চিন্তা একই বৃহত স্ট্রিং এর পুনরায় ব্যবহার)

1000 টি বড় ফাইলের পরে, আপনি কেবল 1000 ছোট নামগুলি সংরক্ষণ করেন, আপনি পুরো 1000 ফাইল স্মৃতিতে রাখবেন! সমাধান: এই দৃশ্যে কেবল ছোট্ট সাবস্ট্রিং.ইন্টার্ন () ব্যবহার করুন


আপনার যদি প্রয়োজন হয় তবে কেবল স্ট্রিং থেকে নতুন স্ট্রিং তৈরি করবেন না কেন?
থরবজর্ন রাভন অ্যান্ডারসন

0

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

সুতরাং মেমরির খরচ হ্রাস করার জন্য ইন্টার্নের () বিকল্প রয়েছে, (== বনাম সমান পারফরম্যান্স বেনিফিটগুলি আমার পক্ষে কোনও সহায়ক নয়)


0

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

এখানে একটি সামান্য কৌশল যা আপনি স্ট্রিংস এবং অন্যান্য অপরিবর্তনীয় অভ্যন্তরীণ অভ্যন্তরীণকরণের জন্য কোন ধরণের প্রক্রিয়াটি ব্যবহার করতে চান এবং উদাহরণ প্রয়োগকরণের উপর আপনাকে কিছুটা নিয়ন্ত্রণ দেয়:

/**
 * Extends the notion of String.intern() to different mechanisms and
 * different types. For example, an implementation can use an
 * LRUCache<T,?>, or a WeakHashMap.
 */
public interface Internalizer<T> {
    public T get(T obj);
}
public static class LRUInternalizer<T> implements Internalizer<T> {
    private final LRUCache<T, T> cache;
    public LRUInternalizer(int size) {
        cache = new LRUCache<T, T>(size) {
            private static final long serialVersionUID = 1L;
            @Override
            protected T retrieve(T key) {
                return key;
            }
        };
    }
    @Override
    public T get(T obj) {
        return cache.get(obj);
    }
}
public class PermGenInternalizer implements Internalizer<String> {
    @Override
    public String get(String obj) {
        return obj.intern();
    }
}

আমি প্রায়শই যখন স্ট্রিম থেকে বা রেজাল্টসেটগুলি থেকে ক্ষেত্রগুলি পড়ি তখন এটি ব্যবহার করি। দ্রষ্টব্য: LRUCacheভিত্তিক একটি সহজ ক্যাশে LinkedHashMap<K,V>। এটি retrieve()সমস্ত ক্যাশে মিস করার জন্য স্বয়ংক্রিয়ভাবে ব্যবহারকারী দ্বারা সরবরাহিত পদ্ধতিটিকে কল করে ।

এটি ব্যবহারের উপায় হ'ল LRUInternalizerআপনার পড়া (বা পড়া) এর আগে একটি তৈরি করা , স্ট্রিংস এবং অন্যান্য ছোট অপরিবর্তনীয় বস্তুগুলিকে অভ্যন্তরীণ করতে এটি ব্যবহার করুন, তারপরে এটিকে মুক্ত করুন। উদাহরণ স্বরূপ:

Internalizer<String> internalizer = new LRUInternalizer(2048);
// ... get some object "input" that stream fields
for (String s : input.nextField()) {
    s = internalizer.get(s);
    // store s...
}

0

আমি এটি প্রায় 36000 কোডের বিষয়বস্তু ক্যাশে করার জন্য ব্যবহার করছি যা সম্পর্কিত নামের সাথে লিঙ্ক করে। আমি ক্যাশে স্ট্রিংগুলি ইন্টার্ন করি কারণ অনেকগুলি কোড একই স্ট্রিংকে নির্দেশ করে।

আমার ক্যাশে স্ট্রিংগুলি অভ্যন্তরীণ করে, আমি নিশ্চিত করছি যে একই কোডগুলিতে নির্দেশিত কোডগুলি একই মেমোরিটিতে নির্দেশ করে, এর ফলে আমার র‌্যামের স্থান বাঁচায়।

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


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

0

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

আপনি যখন আপনার কোডের নির্দিষ্ট অংশগুলিকে অনুকূল করে তুলছেন তখন আমি পারফরম্যান্স مواমনে স্ট্রিং ইন্টার্নিং ব্যবহার করার পরামর্শ দেব।

এছাড়াও মনে রাখবেন যে স্ট্রিং অপরিবর্তনীয় এবং এর নিরীহ ভুল করবেন না

String a = SOME_RANDOM_VALUE
a.intern()

মনে আছে

String a = SOME_RANDOM_VALUE.intern()

0

আপনি যদি স্ট্রিং.ইনটার্নের সীমাহীন প্রতিস্থাপন, এছাড়াও আবর্জনা সংগ্রহের সন্ধান করছেন তবে নীচেরগুলি আমার পক্ষে ভাল কাজ করছে।

private static WeakHashMap<String, WeakReference<String>> internStrings = new WeakHashMap<>();
public static String internalize(String k) {
    synchronized (internStrings) {
        WeakReference<String> weakReference = internStrings.get(k);
        String v = weakReference != null ? weakReference.get() : null;
        if (v == null) {
            v = k;
            internStrings.put(v, new WeakReference<String>(v));
        }
        return v;
    }
}

অবশ্যই, আপনি কতগুলি পৃথক স্ট্রিং থাকবে তা মোটামুটি অনুমান করতে পারেন, তবে কেবল -XX: স্ট্রিং টেবিলসাইজ = হাইঅনুভ্যালু দিয়ে স্ট্রিং.ইনটার্ন () ব্যবহার করুন ।


সফটআরফ আরও সেন্স তৈরি করত।
ওয়াচ করুন

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