2011-08-14 10 views
24

मैं उस स्थान को जानना चाहता हूं जो JVM सिस्टम मेमोरी में ऑब्जेक्ट्स को आवंटित करने के लिए आवंटित करता है।जावा में ऑब्जेक्ट का मेमोरी लोकेशन कैसे प्राप्त कर सकता हूं?

+15

ठीक है, मैं पूछूंगा: क्यों? –

+0

[जावा में चर के मेमोरी पते] का संभावित डुप्लिकेट (http://stackoverflow.com/questions/1961146/memory-address-of-variables-in-java) –

उत्तर

27

यह ऐसा कुछ है जिसे आप शायद नहीं करना चाहते हैं।

आप वास्तव में ऐसा करना चाहते हैं, तो इस कोड की तरह कुछ मदद कर सकता है:

package test; 

import java.lang.reflect.Field; 

import sun.misc.Unsafe; 

public class Addresser 
{ 
    private static Unsafe unsafe; 

    static 
    { 
     try 
     { 
      Field field = Unsafe.class.getDeclaredField("theUnsafe"); 
      field.setAccessible(true); 
      unsafe = (Unsafe)field.get(null); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    public static long addressOf(Object o) 
    throws Exception 
    { 
     Object[] array = new Object[] {o}; 

     long baseOffset = unsafe.arrayBaseOffset(Object[].class); 
     int addressSize = unsafe.addressSize(); 
     long objectAddress; 
     switch (addressSize) 
     { 
      case 4: 
       objectAddress = unsafe.getInt(array, baseOffset); 
       break; 
      case 8: 
       objectAddress = unsafe.getLong(array, baseOffset); 
       break; 
      default: 
       throw new Error("unsupported address size: " + addressSize); 
     }  

     return(objectAddress); 
    } 


    public static void main(String... args) 
    throws Exception 
    { 
     Object mine = "Hi there".toCharArray(); 
     long address = addressOf(mine); 
     System.out.println("Addess: " + address); 

     //Verify address works - should see the characters in the array in the output 
     printBytes(address, 27); 

    } 

    public static void printBytes(long objectAddress, int num) 
    { 
     for (long i = 0; i < num; i++) 
     { 
      int cur = unsafe.getByte(objectAddress + i); 
      System.out.print((char)cur); 
     } 
     System.out.println(); 
    } 
} 

लेकिन

    नहीं JVMs या यहां तक ​​कि विभिन्न संस्करणों
  • वस्तुओं क्योंकि स्थानांतरित कर सकते हैं भर में पोर्टेबल
  • किसी भी समय जीसी का, और जीसी में सिंक्रनाइज़ नहीं कर सकता है, इसलिए परिणाम
  • परीक्षण नहीं किया गया है रॉस सभी आर्किटेक्चर, endianess, आदि बना सकता है यह हर जगह काम नहीं
+1

ऐसा लगता है कि 64-बिट सूर्य जेडीके पर 'unsafe.addressSize() '8 का उपयोग करता है जब UseCompressedOpps चालू होता है। 'Unsafe.arrayIndexScale (ऑब्जेक्ट []। वर्ग) का उपयोग करके, जो उस मामले में 4 लौटाता है, इस तकनीक के साथ काम करने की अधिक संभावना प्रतीत होता है (आखिरकार, आप ऑब्जेक्ट एरे में ऑब्जेक्ट को संग्रहीत कर रहे हैं)। संपीड़ित ओप्स के साथ, लौटाया गया पता एक सही पता नहीं है - इसे 3 बिट्स आदि द्वारा स्थानांतरित किया जा सकता है। – BeeOnRope

9

जेवीएम-विशिष्ट विशेषताओं का उपयोग किए बिना यह नहीं किया जा सकता है। जावा जानबूझकर कार्यान्वयन को अधिक लचीलापन देने के लिए प्रत्येक ऑब्जेक्ट से जुड़े स्थान को छुपाता है (जेवीएम अक्सर कचरा संग्रह करते समय स्मृति में ऑब्जेक्ट्स को चारों ओर ले जाता है) और सुरक्षा में सुधार करने के लिए (आप कच्चे पॉइंटर्स का उपयोग स्मृति को मिटा या किसी भी वस्तु को एक्सेस करने के लिए नहीं कर सकते हैं)।

+0

और 'object.hashCode() 'के डिफ़ॉल्ट कार्यान्वयन के बारे में कैसे? यह वस्तु का स्मृति पता देता है, है ना? क्या यह असुरक्षित वर्ग का उपयोग करता है जिसे @prunge ने बताया था? मुझे पता है कि यह एक मूल विधि है, तो शायद यह सी ++ में एक पॉइंटर-टू-इंट कास्ट है? –

+1

'ऑब्जेक्ट.hashCode() '* * ऑब्जेक्ट का मेमोरी पता वापस नहीं करता है। यह कार्यान्वयन-विशिष्ट है। मैंने एक जेवीएम के जावास्क्रिप्ट कार्यान्वयन पर काम करने में कई महीने बिताए, जहां आप कच्चे पते के साथ काम नहीं कर सकते हैं और प्रत्येक ऑब्जेक्ट के लिए काउंटर I बढ़ाकर 'ऑब्जेक्ट.hashCode()' लागू किया है। कुछ कार्यान्वयन पर यह हो सकता है कि कैसे 'ऑब्जेक्ट.hashCode()' काम करता है, लेकिन क्योंकि कई JVM स्मृति में चारों ओर ऑब्जेक्ट्स ले जाते हैं, आप इस पर भरोसा नहीं कर सकते हैं। – templatetypedef

+0

'System.identityHashcode (ऑब्जेक्ट) 'किसी ऑब्जेक्ट के मेमोरी एड्रेस को वापस करने से काफी जटिल है ... भले ही ऐसा लगता है * ऐसा लगता है। शुरुआत के लिए, जीसी ने वस्तु को स्थानांतरित कर दिया है, भले ही उसे वही मूल्य वापस करना होगा। यह आमतौर पर वस्तु में * बचत * मूल्य शामिल है। (कुछ जेवीएम यह एक चालाक तरीके से करते हैं जो ओवरहेड को कम करता है ... लेकिन आप अंत में भुगतान करते हैं।) –

-2

मैं स्थान कि JVM वस्तुओं

आप नहीं कर सकते करने के लिए आवंटित जानना चाहते हैं, क्योंकि यह अस्तित्व में नहीं है । यह कचरा-कलेक्टर कार्रवाई के कारण समय के साथ बदलता है। ' स्थान' जैसी कोई चीज़ नहीं है।

+2

मेरा क्रेडिट कार्ड शेष बदलता है, दुर्भाग्यवश वे अभी भी मौजूद हैं। – weston

+1

@weston आपके क्रेडिट कार्ड की शेष राशि में परिवर्तन होता है, इसलिए आप इसे हमेशा पर निर्भर नहीं कर सकते हैं। – EJP

+1

उन्होंने यह नहीं कहा कि उन्हें बदलने पर भरोसा करने की आवश्यकता नहीं है। मेरा बिंदु (मजाक) था इसका मतलब यह नहीं है कि यह अस्तित्व में नहीं है। लेकिन वैसे भी इसे पिन करने के तरीके हैं: उदाहरण के लिए जेएनआई महत्वपूर्ण वर्ग जहां स्थान सटीक है और अपरिवर्तित होने की गारंटी है। – weston

-1

आप ऑब्जेक्ट लेआउट को पार्स करने के लिए http://openjdk.java.net/projects/code-tools/jol का उपयोग कर सकते हैं। एक ऑब्जेक्ट के लिए आप इसका उपयोग कर सकते हैं:

System.out.println(
    GraphLayout.parseInstance(someObject).toPrintable()); 
+0

ए) लिंक-केवल उत्तरों को यहां अच्छे उत्तरों नहीं माना जाता है, कृपया [उत्तर] देखें। बी) इस प्रश्न में पहले से ही कई अन्य उच्च गुणवत्ता वाले उत्तरों हैं; यह क्या जोड़ता है? – EJoshuaS

+0

प्रतिक्रिया के लिए धन्यवाद। यह मानक आधुनिक उपकरण - जेओएल के संदर्भ में जोड़ा गया है, जो यहां नहीं हैं। अधिक स्वच्छ और पोर्टेबल तरीका है, जो लेखक के कार्य के लिए असुरक्षित उदाहरण के बजाय कोड की एक पंक्ति लेते हैं। मैंने प्रश्न के लिए कोड उदाहरण भी जोड़े। – egorlitvinenko

संबंधित मुद्दे

 संबंधित मुद्दे