मैं कुछ शोध उद्देश्यों के लिए जावा वस्तुओं के वास्तविक पते को निकालना चाहता हूं। बस स्पष्ट होने के लिए, मैं वास्तव में ऑब्जेक्ट का 48 बिट वर्चुअल एड्रेस चाहता हूं, आईडी या हैशकोड या कोई अद्वितीय पहचानकर्ता नहीं, और मैं समझता हूं कि उन पते को जीसी द्वारा चारों ओर स्थानांतरित किया गया है। मैं stackoverflow से here या here जैसे अन्य पोस्ट पढ़ रहा हूं।जावा ऑब्जेक्ट निष्कर्षण और सत्यापन
निम्नलिखित के लिए मैं @Peter Lawrey -> Is there a way to get a reference address? विधि का उपयोग करता हूं। तो यह वर्ग arrayBaseOffset
विधि के साथ Unsafe
कक्षा का उपयोग करता है। मुझे उन तरीकों के बारे में अजीब बात यह है कि वे प्रत्येक रन (कम से कम मेरे कंप्यूटर पर) के लिए एक ही परिणाम देते हैं जो होने की संभावना नहीं है। सुरक्षा आवंटन के लिए स्मृति आवंटन को यादृच्छिक माना जाना चाहिए।
इसके अलावा, मैंने Pintools के साथ उन विधियों को सत्यापित करने का प्रयास किया जो इंटेल से उपकरण उपकरण है जिसे मैं रन के मेमोरी निशान निकालने के लिए उपयोग करता था। मेरी समस्या यह है कि मैं स्मृति पते प्राप्त करने के लिए उपर्युक्त तरीकों से दिए गए पते के साथ पिंटोल्स के स्मृति ट्रेस में जो कुछ देखता हूं उससे संबंधित नहीं हूं। दिए गए पते को मेरी स्मृति ट्रेस में कभी भी एक्सेस नहीं किया जाता है।
तो मैं सोच रहा हूं कि उन तरीकों से क्या लौटाया गया है और उन परिणामों को अन्य उपकरणों के विरुद्ध कैसे सत्यापित किया गया है।
कुछ जानकारी: मेरी ओएस एक उबंटू x86_64 है, मेरे JVM OpenJDK 64bits 1.8.0_131 है, pintools संस्करण v3.2
है ================ === बिग संपादित करें:
`import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class HelloWorld {
public static void main(String[] args) throws Exception {
Unsafe unsafe = getUnsafeInstance();
Integer i = new Integer(42);
long addr_fromArray;
long addr_fromObject;
/////////////////////////////////////
Object[] objects = {i};
long baseOffset = unsafe.arrayBaseOffset(Object[].class);
addr_fromArray = unsafe.getLong(objects, baseOffset);
long factor1 = 8;
long addr_withFactor = (unsafe.getInt(objects, baseOffset) & 0xFFFFFFFFL) * factor1;
/////////////////////////////////////
class Pointer {
Object pointer;
}
Pointer pointer = new Pointer();
pointer.pointer = i;
long offset = unsafe.objectFieldOffset(Pointer.class.getDeclaredField("pointer"));
addr_fromObject = unsafe.getLong(pointer, offset);
System.out.println("Addr of i from Array : 0x" + Long.toHexString(addr_fromArray));
System.out.println("Addr of i from Object : 0x" + Long.toHexString(addr_fromObject));
System.out.println("Addr of i from factor1 : 0x" + Long.toHexString(addr_withFactor));
System.out.println("!=1");//Launch the pintools instrumentation
for(int a= 0 ; a < 123 ;a++){
i = 10;
}
System.out.println("!=1");//Stop the pintools instrumentation
}
private static Unsafe getUnsafeInstance() throws SecurityException,
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
}
}`
मैं मैं करने के लिए सूचक मिलती है: मुझे लगता है कि मेरे सवाल का अच्छी तरह से नहीं डाल रहा है, इसलिए मुझे एक अधिक परमाणु उदाहरण मिलता है, यहाँ जावा है कि मैं विश्लेषण करने की कोशिश है स्टैक ओवरफ़्लो पर मैंने देखा है कि विभिन्न तरीकों से पूर्णांक। फिर मैं एक मनमाना समय के लिए एक लूप करता हूं ताकि मैं इसे अपने मेमोरी ट्रेस में पहचान सकूं (नोट: मैंने जांच की है कि इस कोड के भीतर कोई जीसी कॉल नहीं होती है)
जब पिनटॉल्स विशिष्ट "! = 1" मानक आउटपुट में लिखा है, यह शुरू होता है/उपकरण
रोक इंस्ट्रूमेंटेशन चरण के दौरान हर पहुँच पर, मैं इस कोड को निष्पादित करें:
VOID RecordAccess(VOID* ip, int id_thread , VOID * addr, int id)
{
PIN_GetLock(&lock, id_thread);
if(startInstru)
{
log1 << "Data accessed: " << addr << "\tThread:" << id_thread << endl;
nb_access++;
uint64_t dummy = reinterpret_cast<uint64_t>(addr);
if(accessPerAddr.count(dummy) == 0)
accessPerAddr.insert(pair<uint64_t,uint64_t>(dummy, 0));
accessPerAddr[dummy]++;
}
}
इस pintools साथ
, मैं एक स्मृति का पता लगाने + पर कैसे एक आयतचित्र उत्पन्न कई बार प्रत्येक मेमोरी पते का उपयोग किया जाता है। नोट: प्रत्येक थ्रेड के उपकरण के लिए "follow_execv" विकल्प के साथ पिनटोल लॉन्च किया गया है।
1) मैं मुद्रित मैं किसी भी पते पर (या इस पते पर पास करने के लिए कोई पहुंच देखें):
2 समस्याएं देखें। मुझे पिंटोल्स पर भरोसा है क्योंकि मैंने पहले काफी उपयोग किया है लेकिन शायद पिंटोल्स सही पते को पुनः प्राप्त करने में सक्षम नहीं है।
2) मुझे 123 बार (या इसके करीब) तक कोई पता नहीं देखा जा रहा है। इसके लिए मेरे विचार यह है कि शायद JVM ऑप्टिमाइज़ेशन निष्पादित करता है क्योंकि यह देखता है कि निष्पादित कोड का कोई प्रभाव नहीं है, इसलिए यह इसे निष्पादित नहीं करता है। हालांकि, मैंने लूप के अंदर एक बेहतर जटिल निर्देश के बिना एक अधिक जटिल निर्देश (जिसे यादृच्छिक संख्या संग्रहित करने की तरह अनुकूलित नहीं किया जा सकता) के साथ प्रयास किया।
मुझे यहां दूसरे चरण में जीसी प्रभाव के बारे में ज्यादा परवाह नहीं है। मैं केवल अपने जावा ऐप से मूल पते निकालने में सक्षम होना चाहता हूं, मुझे यकीन है कि पिंटोल्स मुझे दे रहा है।
आप अपने कोड –
'मेमोरी आवंटन को सुरक्षा कारणों से यादृच्छिक माना जाना चाहिए।' क्या आपके पास जावा में वास्तव में ऐसा कोई संदर्भ है? इस कथन में सी में कुछ समझ है, जहां बफर ओवरफ़्लो कोड निष्पादन का परिणाम हो सकता है। –
अगर यह मदद करता है तो कुछ कोड जोड़ा गया! –