What Is an "Internal Address" in Java

What is an internal address in Java?

This is clearly implementation-specific.

Below I include the Object.hashCode() implementation used in OpenJDK 7.

The function supports six different calculation methods, only two of which take any notice of the object's address (the "address" being the C++ oop cast to intptr_t). One of the two methods uses the address as-is, whereas the other does some bit twiddling and then mashes the result with an infrequently-updated random number.

Of the remaining methods, one returns a constant (presumably for testing), one returns sequential numbers, and the rest are based on pseudo-random sequences.

It would appear that the method can be chosen at runtime, and the default seems to be method 0, which is os::random(). The latter is a linear congruential generator, with an alleged race condition thrown in. :-) The race condition is acceptable because at worst it would result in two objects sharing the same hash code; this does not break any invariants.

The computation is performed the first time a hash code is required. To maintain consistency, the result is then stored in the object's header and is returned on subsequent calls to hashCode(). The caching is done outside this function.

In summary, the notion that Object.hashCode() is based on the object's address is largely a historic artefact that has been obsoleted by the properties of modern garbage collectors.

// hotspot/src/share/vm/runtime/synchronizer.hpp

// hashCode() generation :
//
// Possibilities:
// * MD5Digest of {obj,stwRandom}
// * CRC32 of {obj,stwRandom} or any linear-feedback shift register function.
// * A DES- or AES-style SBox[] mechanism
// * One of the Phi-based schemes, such as:
// 2654435761 = 2^32 * Phi (golden ratio)
// HashCodeValue = ((uintptr_t(obj) >> 3) * 2654435761) ^ GVars.stwRandom ;
// * A variation of Marsaglia's shift-xor RNG scheme.
// * (obj ^ stwRandom) is appealing, but can result
// in undesirable regularity in the hashCode values of adjacent objects
// (objects allocated back-to-back, in particular). This could potentially
// result in hashtable collisions and reduced hashtable efficiency.
// There are simple ways to "diffuse" the middle address bits over the
// generated hashCode values:
//

static inline intptr_t get_next_hash(Thread * Self, oop obj) {
intptr_t value = 0 ;
if (hashCode == 0) {
// This form uses an unguarded global Park-Miller RNG,
// so it's possible for two threads to race and generate the same RNG.
// On MP system we'll have lots of RW access to a global, so the
// mechanism induces lots of coherency traffic.
value = os::random() ;
} else
if (hashCode == 1) {
// This variation has the property of being stable (idempotent)
// between STW operations. This can be useful in some of the 1-0
// synchronization schemes.
intptr_t addrBits = intptr_t(obj) >> 3 ;
value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ;
} else
if (hashCode == 2) {
value = 1 ; // for sensitivity testing
} else
if (hashCode == 3) {
value = ++GVars.hcSequence ;
} else
if (hashCode == 4) {
value = intptr_t(obj) ;
} else {
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
unsigned t = Self->_hashStateX ;
t ^= (t << 11) ;
Self->_hashStateX = Self->_hashStateY ;
Self->_hashStateY = Self->_hashStateZ ;
Self->_hashStateZ = Self->_hashStateW ;
unsigned v = Self->_hashStateW ;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
Self->_hashStateW = v ;
value = v ;
}

value &= markOopDesc::hash_mask;
if (value == 0) value = 0xBAD ;
assert (value != markOopDesc::no_hash, "invariant") ;
TEVENT (hashCode: GENERATE) ;
return value;
}

Java get local internal Address

If Im not understand wrong you can get it like this :

public String getMyFacesIp() {
String ip = "";
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while(interfaces.hasMoreElements()) {
NetworkInterface iface = interfaces.nextElement();
if(iface.isLoopback() || !iface.isUp()) {
continue;
}

Enumeration<InetAddress> addresses = iface.getInetAddresses();
while(addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
ip = addr.getHostAddress();
if(ip.startsWith("192")) {
return ip;
}
}
}
} catch (Exception e) {}
return ip;

}

Getting the IP address of the current machine using Java

import java.net.DatagramSocket;
import java.net.InetAddress;

try(final DatagramSocket socket = new DatagramSocket()){
socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
ip = socket.getLocalAddress().getHostAddress();
}

This way works well when there are multiple network interfaces. It always returns the preferred outbound IP. The destination 8.8.8.8 is not needed to be reachable.

Connect on a UDP socket has the following effect: it sets the destination for Send/Recv, discards all packets from other addresses, and - which is what we use - transfers the socket into "connected" state, settings its appropriate fields. This includes checking the existence of the route to the destination according to the system's routing table and setting the local endpoint accordingly. The last part seems to be undocumented officially but it looks like an integral trait of Berkeley sockets API (a side effect of UDP "connected" state) that works reliably in both Windows and Linux across versions and distributions.

So, this method will give the local address that would be used to connect to the specified remote host. There is no real connection established, hence the specified remote ip can be unreachable.

Edit:

As @macomgil says, for MacOS you can do this:

Socket socket = new Socket();
socket.connect(new InetSocketAddress("google.com", 80));
System.out.println(socket.getLocalAddress());

Java getting my IP address

The NetworkInterface class contains all the relevant methods, but be aware that there's no such thing as "my IP". A machine can have multiple interfaces and each interface can have multiple IPs.

You can list them all with this class but which interface and IP you choose from the list depends on what you exactly need to use this IP for.

(InetAddress.getLocalHost() doesn't consult your interfaces, it simply returns constant 127.0.0.1 (for IPv4))

Find server ip address on local network

You could use the hostname of the server instead of the IP. When IP changes the hostname should stay the same.

You can establish the hostname in many ways. Either programmatically:

 String hostName = InetAddress.getLocalHost().getHostName();

Or with an OS command or a tool.

For example, on Windows it could be

ipconfig /all

On Linux it could probably be

hostname

or

hostnamectl

Once you know the hostname you could use it to establish a connection. Alternatively, you could also get the IP of the server programmatically on any client in the local network. In Java you could use the following code:

InetAddress.getByName("serverHostName").getHostAddress()

Check whether the ipAddress is in private range

This is a quick hack I generated to test my own address.

import java.net.InetAddress;
import java.net.UnknownHostException;

public class LocalAddress {

public static void main(String[] args) {
InetAddress address = null;
try {
address = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
if (address.isSiteLocalAddress()) {
System.out.println("Site Local Address: " + address.getHostAddress());
} else {
System.out.println("Routeable Address: " + address.getHostAddress());
}
}

}

EDIT: This code has not been tested for the link local addresses, localhost, or address blocks reserved for documentation. The first two cases have methods that return them. The last is not referenced in the documentation of the class.



Related Topics



Leave a reply



Submit