|
Memory and the Java Runtime.exec Process |
|
Written by Keith Petty
|
|
Wednesday, 21 February 2007 11:01 |
|
Today, we will be learning how to get a Mac address off of your machine and that Java's memory management does not work on external processes run by the operating system even if they were invoked by a call from within a running Java class.
The very most important part of this exercise is found on line #111
If we do not destroy the process that we started by calling the operating system it will remain open in memory even after we finish running our program in the JVM. For this example we will assume that we could be dealing with the Windows operating system or the Linux operating system. 1 import java.io.*; 2 import java.util.regex.*; 3 4 public class MyMac { 5 6 // main method 7 public static void main(String[] args) { 8 9 // create an instance 10 MyMac mac1 = new MyMac(); 11 12 // call the getMacAddress() method and print the value returned 13 System.out.println(mac1.getMacAddress()); 14 } 15 16 // getMacAddress() method 17 private StringBuffer getMacAddress() { 18 19 // StringBuffer to be used to return info about the Mac address 20 StringBuffer myMacAddress = new StringBuffer(); 21 22 // The Runtime.exec() method returns an instance of a subclass of Process 23 Process myProc = null; 24 25 // surround with a try catch block 26 try { 27 28 // we will be walking through each line of 29 // output produced by invoking a command line process 30 // so we will store them one at a time in this String 31 String currentLine = ""; 32 33 // the operating systems name as referenced by the System 34 String osName = System.getProperty("os.name"); 35 36 // a regular expression used to match the area of text we want 37 String macRegExp = ""; 38 39 if(osName.startsWith("Windows")) { // Windows operating system will run this 40 41 // the regular expression we will be matching for the Mac address on Windows 42 macRegExp = "[\\da-zA-Z]{1,2}\\-[\\da-zA-Z]{1,2}\\-[\\da-zA-Z]" + 43 "{1,2}\\-[\\da-zA-Z]{1,2}\\-[\\da-zA-Z]{1,2}\\-[\\da-zA-Z]{1,2}"; 44 // get the live Process returned through the call to the 45 // Runtime.getRuntime().exec method and invoking 46 // the Windows command ipconfig /all 47 myProc = Runtime.getRuntime().exec("ipconfig /all"); 48 } 49 else if(osName.startsWith("Linux")) { // Linux operating system runs this 50 51 // the regular expression we will be matching for the Mac address on Linux 52 macRegExp = "[\\da-zA-Z]{1,2}\\:[\\da-zA-Z]{1,2}\\:[\\da-zA-Z]" + 53 "{1,2}\\:[\\da-zA-Z]{1,2}\\:[\\da-zA-Z]{1,2}\\:[\\da-zA-Z]{1,2}"; 54 // get the live Process returned through the call to the 55 // Runtime.getRuntime().exec method and invoking 56 // the Linux command /sbin/ifconfig -a 57 myProc = Runtime.getRuntime().exec("/sbin/ifconfig -a"); 58 } 59 else{ 60 // other operating systems are not supported 61 // we are done here 62 myMacAddress.append("Only works on Windows or Linux systems"); 63 64 // exiting method now 65 return myMacAddress; 66 } 67 68 myMacAddress.append("Mac address(es)"); 69 70 // we'll wrap a buffer around the InputStream we get from the "myProc" Process 71 BufferedReader in = new BufferedReader( 72 new InputStreamReader(myProc.getInputStream())); 73 // compile the macRegExp string into a Pattern 74 Pattern macPattern = Pattern.compile(".*" + macRegExp + ".*"); 75 76 // a Matcher object for matching the regular expression to the string 77 Matcher macMtch = null; 78 79 while((currentLine = in.readLine()) != null) { 80 81 // walk through each line and try to match the pattern 82 macMtch = macPattern.matcher(currentLine); 83 84 if(macMtch.matches()) { 85 86 // it matched so we split the line 87 String[] splitLine = currentLine.split(macRegExp); 88 89 for(int a = 0; a < splitLine.length; a++) { 90 // REPLACE ALL PORTIONS of the currentLine 91 // that do not match the expression 92 // with an empty string 93 currentLine = currentLine.replaceAll(splitLine[a].toString(), ""); 94 } 95 96 // mac address(es) returned in the StringBuffer 97 myMacAddress.append(System.getProperty("line.separator") + currentLine); 98 99 // reset the matcher just in case we have more than one mac address 100 macMtch.reset(); 101 // after all there could more than one NIC card! 102 } 103 } 104 105 // last but 106 // MOST IMPORTANT !!!!!!!!!!!! 107 // we must destroy the process 108 // or the "operating system" 109 // won't "close the process" or 110 // clean up "it's memory allocation" 111 myProc.destroy(); 112 } 113 catch(java.io.IOException e) { 114 e.printStackTrace(); 115 } 116 return myMacAddress; 117 } 118 } |