求Java虚拟机详解? 求一名看过深入理解JAVA虚拟机这本书的老鸟

java\u865a\u62df\u673a\u5de5\u4f5c\u539f\u7406\uff1f

\u4ece\u5b8f\u89c2\u4e0a\u4ecb\u7ecd\u4e00\u4e0bJava\u865a\u62df\u673a\u7684\u5de5\u4f5c\u539f\u7406\u3002\u4ece\u6700\u521d\u7f16\u5199\u7684Java\u6e90\u6587\u4ef6\uff08.java\u6587\u4ef6\uff09\u662f\u5982\u4f55\u4e00\u6b65\u6b65\u6267\u884c\u7684\uff0c\u5982\u4e0b\u56fe\u6240\u793a\uff0c\u9996\u5148Java\u6e90\u6587\u4ef6\u7ecf\u8fc7\u524d\u7aef\u7f16\u8bd1\u5668\uff08javac\u6216ECJ\uff09\u5c06.java\u6587\u4ef6\u7f16\u8bd1\u4e3aJava\u5b57\u8282\u7801\u6587\u4ef6\uff0c\u7136\u540eJRE\u52a0\u8f7dJava\u5b57\u8282\u7801\u6587\u4ef6\uff0c\u8f7d\u5165\u7cfb\u7edf\u5206\u914d\u7ed9JVM\u7684\u5185\u5b58\u533a\uff0c\u7136\u540e\u6267\u884c\u5f15\u64ce\u89e3\u91ca\u6216\u7f16\u8bd1\u7c7b\u6587\u4ef6\uff0c\u518d\u7531\u5373\u65f6\u7f16\u8bd1\u5668\u5c06\u5b57\u8282\u7801\u8f6c\u5316\u4e3a\u673a\u5668\u7801\u3002\u4e3b\u8981\u4ecb\u7ecd\u4e0b\u56fe\u4e2d\u7684\u7c7b\u52a0\u8f7d\u5668\u548c\u8fd0\u884c\u65f6\u6570\u636e\u533a\u4e24\u4e2a\u90e8\u5206\u3002

\uff081\uff09\u7c7b\u52a0\u8f7d\u6307\u5c06\u7c7b\u7684\u5b57\u8282\u7801\u6587\u4ef6\uff08.class\uff09\u4e2d\u7684\u4e8c\u8fdb\u5236\u6570\u636e\u8bfb\u5165\u5185\u5b58\uff0c\u5c06\u5176\u653e\u5728\u8fd0\u884c\u65f6\u6570\u636e\u533a\u7684\u65b9\u6cd5\u533a\u5185\uff0c\u7136\u540e\u5728\u5806\u4e0a\u521b\u5efajava.lang.Class\u5bf9\u8c61\uff0c\u5c01\u88c5\u7c7b\u5728\u65b9\u6cd5\u533a\u5185\u7684\u6570\u636e\u7ed3\u6784\u3002\u7c7b\u52a0\u8f7d\u7684\u6700\u7ec8\u4ea7\u54c1\u662f\u4f4d\u4e8e\u5806\u4e2d\u7684\u7c7b\u5bf9\u8c61\uff0c\u7c7b\u5bf9\u8c61\u5c01\u88c5\u4e86\u7c7b\u5728\u65b9\u6cd5\u533a\u5185\u7684\u6570\u636e\u7ed3\u6784\uff0c\u5e76\u4e14\u5411JAVA\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u8bbf\u95ee\u65b9\u6cd5\u533a\u5185\u6570\u636e\u7ed3\u6784\u7684\u63a5\u53e3\u3002\u5982\u4e0b\u662f\u7c7b\u52a0\u8f7d\u5668\u7684\u5c42\u6b21\u5173\u7cfb\u56fe\u3002


\u542f\u52a8\u7c7b\u52a0\u8f7d\u5668\uff08BootstrapClassLoader\uff09\uff1a\u5728JVM\u8fd0\u884c\u65f6\u88ab\u521b\u5efa\uff0c\u8d1f\u8d23\u52a0\u8f7d\u5b58\u653e\u5728JDK\u5b89\u88c5\u76ee\u5f55\u4e0b\u7684jre\lib\u7684\u7c7b\u6587\u4ef6\uff0c\u6216\u8005\u88ab-Xbootclasspath\u53c2\u6570\u6307\u5b9a\u7684\u8def\u5f84\u4e2d\uff0c\u5e76\u4e14\u80fd\u88ab\u865a\u62df\u673a\u8bc6\u522b\u7684\u7c7b\u5e93\uff08\u5982rt.jar\uff0c\u6240\u6709\u7684java.*\u5f00\u5934\u7684\u7c7b\u5747\u88abBootstrap ClassLoader\u52a0\u8f7d\uff09\u3002\u542f\u52a8\u7c7b\u65e0\u6cd5\u88abJAVA\u7a0b\u5e8f\u76f4\u63a5\u5f15\u7528\u3002
\u6269\u5c55\u7c7b\u52a0\u8f7d\u5668\uff08Extension ClassLoader\uff09\uff1a\u8be5\u7c7b\u52a0\u8f7d\u5668\u8d1f\u8d23\u52a0\u8f7dJDK\u5b89\u88c5\u76ee\u5f55\u4e0b\u7684\jre\lib\ext\u7684\u7c7b\uff0c\u6216\u8005\u7531java.ext.dirs\u7cfb\u7edf\u53d8\u91cf\u6307\u5b9a\u8def\u5f84\u4e2d\u7684\u6240\u6709\u7c7b\u5e93\uff0c\u5f00\u53d1\u8005\u4e5f\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u6269\u5c55\u7c7b\u52a0\u8f7d\u5668\u3002
\u5e94\u7528\u7a0b\u5e8f\u7c7b\u52a0\u8f7d\u5668\uff08AppClassLoader\uff09\uff1a\u8d1f\u8d23\u52a0\u8f7d\u7528\u6237\u7c7b\u8def\u5f84\uff08Classpath\uff09\u6240\u6307\u5b9a\u7684\u7c7b\uff0c\u5f00\u53d1\u8005\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u8be5\u7c7b\u52a0\u8f7d\u5668\uff0c\u5982\u679c\u5e94\u7528\u7a0b\u5e8f\u4e2d\u6ca1\u6709\u5b9a\u4e49\u8fc7\u81ea\u5df1\u7684\u7c7b\u52a0\u8f7d\u5668\uff0c\u8be5\u7c7b\u52a0\u8f7d\u5668\u4e3a\u9ed8\u8ba4\u7684\u7c7b\u52a0\u8f7d\u5668\u3002
\u7528\u6237\u81ea\u5b9a\u4e49\u7c7b\u52a0\u8f7d\u5668\uff08User ClassLoader\uff09\uff1aJVM\u81ea\u5e26\u7684\u7c7b\u52a0\u8f7d\u5668\u662f\u4ece\u672c\u5730\u6587\u4ef6\u7cfb\u7edf\u52a0\u8f7d\u6807\u51c6\u7684java class\u6587\u4ef6\uff0c\u800c\u81ea\u5b9a\u4e49\u7684\u7c7b\u52a0\u8f7d\u5668\u53ef\u4ee5\u505a\u5230\u5728\u6267\u884c\u975e\u7f6e\u4fe1\u4ee3\u7801\u4e4b\u524d\uff0c\u81ea\u52a8\u9a8c\u8bc1\u6570\u5b57\u7b7e\u540d\uff0c\u52a8\u6001\u5730\u521b\u5efa\u7b26\u5408\u7528\u6237\u7279\u5b9a\u9700\u8981\u7684\u5b9a\u5236\u5316\u6784\u5efa\u7c7b\uff0c\u4ece\u7279\u5b9a\u7684\u573a\u6240\uff08\u6570\u636e\u5e93\u3001\u7f51\u7edc\u4e2d\uff09\u53d6\u5f97java class\u3002
\u6ce8\u610f\u5982\u4e0a\u7684\u7c7b\u52a0\u8f7d\u5668\u5e76\u4e0d\u662f\u901a\u8fc7\u7ee7\u627f\u7684\u65b9\u5f0f\u5b9e\u73b0\u7684\uff0c\u800c\u662f\u901a\u8fc7\u7ec4\u5408\u7684\u65b9\u5f0f\u5b9e\u73b0\u7684\u3002\u800cJAVA\u865a\u62df\u673a\u7684\u52a0\u8f7d\u6a21\u5f0f\u662f\u4e00\u79cd\u59d4\u6d3e\u6a21\u5f0f\uff0c\u5982\u4e0a\u56fe\u4e2d\u76841-7\u6b65\u6240\u793a\u3002\u4e0b\u5c42\u7684\u52a0\u8f7d\u5668\u80fd\u591f\u770b\u5230\u4e0a\u5c42\u52a0\u8f7d\u5668\u4e2d\u7684\u7c7b\uff0c\u53cd\u4e4b\u5219\u4e0d\u884c\u3002\u7c7b\u52a0\u8f7d\u5668\u53ef\u4ee5\u52a0\u8f7d\u7c7b\u4f46\u662f\u4e0d\u80fd\u5378\u8f7d\u7c7b\u3002\u8bf4\u4e86\u4e00\u5927\u5806\uff0c\u8fd8\u662f\u611f\u89c9\u9700\u8981\u62ff\u70b9\u4ee3\u7801\u8bf4\u4e8b\u3002
\u9996\u5148\u5148\u5b9a\u4e49\u81ea\u5df1\u7684\u7c7b\u52a0\u8f7d\u5668MyClassLoader\uff0c\u7ee7\u627f\u81eaClassLoader\uff0c\u5e76\u8986\u76d6\u4e86\u7236\u7c7b\u7684findClass(String name)\u65b9\u6cd5\uff0c\u5982\u4e0b\uff1a

\u5229\u7528\u5b9a\u4e49\u7684\u7c7b\u52a0\u8f7d\u5668\u52a0\u8f7d\u6307\u5b9a\u7684\u5b57\u8282\u7801\u6587\u4ef6\uff0c\u5982\u901a\u8fc7MyClassLoader\u52a0\u8f7dC:\\Users\\Administrator\\\u4e0b\u7684Test.class\u5b57\u8282\u7801\u6587\u4ef6\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a

\uff082\uff09\u8fd0\u884c\u65f6\u6570\u636e\u533a
\u5b57\u8282\u7801\u7684\u52a0\u8f7d\u7b2c\u4e00\u6b65\uff0c\u5176\u540e\u5206\u522b\u662f\u8ba4\u8bc1\u3001\u51c6\u5907\u3001\u89e3\u6790\u3001\u521d\u59cb\u5316\uff0c\u90a3\u4e48\u8fd9\u4e9b\u6b65\u9aa4\u53c8\u5177\u4f53\u505a\u4e86\u54ea\u4e9b\u5de5\u4f5c\uff0c\u5982\u4e0b\u56fe\u6240\u793a\uff1a

\uff083\uff09\u5982\u4e0b\u5c06\u4ecb\u7ecd\u8fd0\u884c\u65f6\u6570\u636e\u533a\uff0c\u4e3b\u8981\u5206\u4e3a\u65b9\u6cd5\u533a\u3001Java\u5806\u3001\u865a\u62df\u673a\u6808\u3001\u672c\u5730\u65b9\u6cd5\u6808\u3001\u7a0b\u5e8f\u8ba1\u6570\u5668\u3002\u5176\u4e2d\u65b9\u6cd5\u533a\u548cJava\u5806\u4e00\u6837\uff0c\u662f\u5404\u4e2a\u7ebf\u7a0b\u5171\u4eab\u7684\u5185\u5b58\u533a\u57df\uff0c\u800c\u865a\u62df\u673a\u6808\u3001\u672c\u5730\u65b9\u6cd5\u6808\u3001\u7a0b\u5e8f\u8ba1\u6570\u5668\u662f\u7ebf\u7a0b\u79c1\u6709\u7684\u5185\u5b58\u533a\u3002

Java\u5806\uff1aJava\u5806\u662fJava\u865a\u62df\u673a\u6240\u7ba1\u7406\u7684\u5185\u5b58\u4e2d\u6700\u5927\u7684\u4e00\u5757\uff0c\u88ab\u8fdb\u7a0b\u7684\u6240\u6709\u7ebf\u7a0b\u5171\u4eab\uff0c\u5728\u865a\u62df\u673a\u542f\u52a8\u65f6\u88ab\u521b\u5efa\u3002\u8be5\u533a\u57df\u7684\u552f\u4e00\u76ee\u7684\u5c31\u662f\u5b58\u653e\u5bf9\u8c61\u5b9e\u4f8b\uff0c\u51e0\u4e4e\u6240\u6709\u7684\u5bf9\u8c61\u5b9e\u4f8b\u90fd\u5728\u8fd9\u91cc\u5206\u914d\u5185\u5b58\uff0c\u968f\u7740JIT\u7f16\u8bd1\u5668\u7684\u53d1\u5c55\u4e0e\u9003\u9038\u5206\u652f\u6280\u672f\u9010\u6e10\u6210\u719f\uff0c\u6808\u4e0a\u5206\u914d\u3001\u6807\u91cf\u66ff\u6362\u7b49\u4f18\u5316\u6280\u672f\u4f7f\u5f97\u5bf9\u8c61\u5728\u5806\u4e0a\u7684\u5206\u914d\u5185\u5b58\u53d8\u5f97\u4e0d\u662f\u90a3\u4e48\u201c\u7edd\u5bf9\u201d\u3002Java\u5806\u662f\u5783\u573e\u6536\u96c6\u5668\u7ba1\u7406\u7684\u4e3b\u8981\u533a\u57df\u3002\u7531\u4e8e\u73b0\u5728\u7684\u6536\u96c6\u5668\u57fa\u672c\u90fd\u91c7\u7528\u5206\u4ee3\u6536\u96c6\u7b97\u6cd5\uff0c\u6240\u4ee5Java\u5806\u4e2d\u8fd8\u53ef\u4ee5\u5206\u4e3a\u8001\u5e74\u4ee3\u548c\u65b0\u751f\u4ee3(Eden\u3001From Survivor\u3001To Survivor)\u3002\u6839\u636eJava\u865a\u62df\u673a\u89c4\u8303\uff0cJava\u5806\u53ef\u4ee5\u5904\u4e8e\u7269\u7406\u4e0a\u4e0d\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u53ea\u8981\u903b\u8f91\u4e0a\u8fde\u7eed\u5373\u53ef\u3002\u8be5\u533a\u57df\u7684\u5927\u5c0f\u53ef\u4ee5\u901a\u8fc7-Xmx\u548c-Xms\u53c2\u6570\u6765\u6269\u5c55\uff0c\u5982\u679c\u5806\u4e2d\u6ca1\u6709\u5185\u5b58\u5b8c\u6210\u5b9e\u4f8b\u5206\u914d\uff0c\u5e76\u4e14\u5806\u4e5f\u65e0\u6cd5\u6269\u5c55\uff0c\u5c06\u4f1a\u629b\u51faOutOfMemoryError\u5f02\u5e38\u3002
\u65b9\u6cd5\u533a\uff1a\u7528\u4e8e\u5b58\u50a8\u88abJava\u865a\u62df\u673a\u52a0\u8f7d\u7684\u7c7b\u4fe1\u606f\u3001\u5e38\u91cf\u3001\u9759\u6001\u53d8\u91cf\u3001\u5373\u65f6\u7f16\u8bd1\u5668\u7f16\u8bd1\u540e\u7684\u4ee3\u7801\u7b49\u6570\u636e\u3002\u4e0d\u540c\u4e8eJava\u5806\u7684\u662f\uff0cJava\u865a\u62df\u673a\u89c4\u8303\u5bf9\u65b9\u6cd5\u533a\u7684\u9650\u5236\u975e\u5e38\u5bbd\u677e\uff0c\u53ef\u4ee5\u9009\u62e9\u4e0d\u5b9e\u73b0\u5783\u573e\u6536\u96c6\u3002\u4f46\u5e76\u975e\u6570\u636e\u8fdb\u5165\u4e86\u65b9\u6cd5\u533a\u5c31\u201c\u6c38\u4e45\u201d\u5b58\u5728\u4e86\uff0c\u8fd9\u533a\u57df\u5185\u5b58\u56de\u6536\u76ee\u6807\u4e3b\u8981\u662f\u9488\u5bf9\u5e38\u91cf\u6c60\u7684\u56de\u6536\u548c\u5bf9\u7c7b\u578b\u7684\u5378\u8f7d\u3002\u5982\u679c\u8be5\u533a\u57df\u5185\u5b58\u4e0d\u8db3\u4e5f\u4f1a\u629b\u51faOutOfMemoryError\u5f02\u5e38\u3002
\u5e38\u91cf\u6c60\uff1a\u8fd9\u4e2a\u540d\u8bcd\u53ef\u80fd\u5927\u5bb6\u4e5f\u7ecf\u5e38\u89c1\uff0c\u662f\u65b9\u6cd5\u533a\u7684\u4e00\u90e8\u5206\u3002Class\u6587\u4ef6\u9664\u4e86\u6709\u7c7b\u7684\u7248\u672c\u3001\u5b57\u6bb5\u3001\u65b9\u6cd5\u3001\u63a5\u53e3\u7b49\u63cf\u8ff0\u4fe1\u606f\u5916\uff0c\u8fd8\u6709\u4e00\u9879\u4fe1\u606f\u5c31\u662f\u5e38\u91cf\u6c60\uff0c\u7528\u4e8e\u5b58\u653e\u7f16\u8bd1\u671f\u751f\u6210\u7684\u5404\u79cd\u5b57\u9762\u91cf\u548c\u7b26\u53f7\u5f15\u7528\u3002Java\u865a\u62df\u673a\u8fd0\u884c\u671f\u95f4\uff0c\u4e5f\u53ef\u80fd\u5c06\u65b0\u7684\u5e38\u91cf\u653e\u5165\u5e38\u91cf\u6c60\uff08\u5982String\u7c7b\u7684intern()\u65b9\u6cd5\uff09\u3002
\u865a\u62df\u673a\u6808\uff1a\u7ebf\u7a0b\u79c1\u6709\uff0c\u751f\u547d\u5468\u671f\u4e0e\u7ebf\u7a0b\u76f8\u540c\u3002\u865a\u62df\u673a\u6808\u63cf\u8ff0\u7684\u662fJava\u65b9\u6cd5\u6267\u884c\u7684\u5185\u5b58\u6a21\u578b\uff1a\u6bcf\u4e2a\u65b9\u6cd5\u5728\u6267\u884c\u65f6\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u6808\u5e27\u7528\u4e8e\u5b58\u50a8\u5c40\u90e8\u53d8\u91cf\u8868\u3001\u64cd\u4f5c\u6570\u6808\u3001\u52a8\u6001\u94fe\u63a5\u3001\u65b9\u6cd5\u51fa\u53e3\u7b49\u4fe1\u606f\u3002\u6bcf\u4e2a\u65b9\u6cd5\u4ece\u8c03\u7528\u76f4\u81f3\u6267\u884c\u5b8c\u6210\u7684\u8fc7\u7a0b\uff0c\u5c31\u5bf9\u5e94\u7740\u4e00\u4e2a\u6808\u5e27\u5728\u865a\u62df\u673a\u6808\u4e2d\u5165\u6808\u5230\u51fa\u6808\u7684\u8fc7\u7a0b\u3002\u5982\u679c\u8bf7\u6c42\u7684\u7ad9\u6df1\u5ea6\u5927\u4e8e\u865a\u62df\u673a\u6240\u5141\u8bb8\u7684\u6df1\u5ea6\uff0c\u5c06\u629b\u51faStackOverflowError\u5f02\u5e38\uff0c\u865a\u62df\u673a\u6808\u5728\u52a8\u6001\u6269\u5c55\u65f6\u5982\u679c\u65e0\u6cd5\u7533\u8bf7\u5230\u8db3\u591f\u7684\u5185\u5b58\uff0c\u5c31\u4f1a\u629b\u51faOutOfMemoryError\u5f02\u5e38\u3002

\u8fc7\u6700\u7b80\u5355\u7684\u4e00\u6bb5\u4ee3\u7801\u89e3\u91ca\u4e00\u4e0b\uff0c\u7a0b\u5e8f\u5728\u8fd0\u884c\u65f6\u6570\u636e\u533a\u4e2a\u90e8\u5206\u7684\u53d8\u5316\u60c5\u51b5\u3002

\uff084\uff09\u901a\u8fc7\u7f16\u8bd1\u5668\u5c06Test.java\u6587\u4ef6\u7f16\u8bd1\u4e3aTest.class\uff0c\u5229\u7528javap -verbose Test.class\u5bf9\u7f16\u8bd1\u540e\u7684\u5b57\u8282\u7801\u8fdb\u884c\u5206\u6790\uff0c\u5982\u4e0b\u56fe\u6240\u793a\uff1a

\uff085\uff09\u770b\u770b\u8fd0\u884c\u65f6\u6570\u636e\u533a\u7684\u53d8\u5316\uff1a

\u6211\u524d\u51e0\u5929\u521a\u4e70\u4e86\u8fd9\u672c\u4e66\uff0c\u5e0c\u671b\u53ef\u4ee5\u4e92\u76f8\u8fdb\u6b65

1   Java技术与Java虚拟机

说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。它们的关系如下图所示:

图1   Java四个方面的关系

运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件)。最后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。从上图也可以看出Java平台由Java虚拟机和 Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平台上。这个平台的结构如下图所示:

在Java平台的结构中, 可以看出,Java虚拟机(JVM) 处在核心的位置,是程序与底层操作系统和硬件无关的关键。它的下方是移植接口,移植接口由两部分组成:适配器和Java操作系统, 其中依赖于平台的部分称为适配器;JVM 通过移植接口在具体的平台和操作系统上实现;在JVM 的上方是Java的基本类库和扩展类库以及它们的API, 利用Java API编写的应用程序(application) 和小程序(Java applet) 可以在任何Java平台上运行而无需考虑底层平台, 就是因为有Java虚拟机(JVM)实现了程序与操作系统的分离,从而实现了Java 的平台无关性。

那么到底什么是Java虚拟机(JVM)呢?通常我们谈论JVM时,我们的意思可能是:

对JVM规范的的比较抽象的说明; 

 

对JVM的具体实现; 

 

在程序运行期间所生成的一个JVM实例。 

对JVM规范的的抽象说明是一些概念的集合,它们已经在书《The Java Virtual Machine Specification》(《Java虚拟机规范》)中被详细地描述了;对JVM的具体实现要么是软件,要么是软件和硬件的组合,它已经被许多生产厂商所实现,并存在于多种平台之上;运行Java程序的任务由JVM的运行期实例单个承担。在本文中我们所讨论的Java虚拟机(JVM)主要针对第三种情况而言。它可以被看成一个想象中的机器,在实际的计算机上通过软件模拟来实现,有自己想象中的硬件,如处理器、堆栈、寄存器等,还有自己相应的指令系统。

JVM在它的生存周期中有一个明确的任务,那就是运行Java程序,因此当Java程序启动的时候,就产生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。下面我们从JVM的体系结构和它的运行过程这两个方面来对它进行比较深入的研究。

2   Java虚拟机的体系结构

刚才已经提到,JVM可以由不同的厂商来实现。由于厂商的不同必然导致JVM在实现上的一些不同,然而JVM还是可以实现跨平台的特性,这就要归功于设计JVM时的体系结构了。

我们知道,一个JVM实例的行为不光是它自己的事,还涉及到它的子系统、存储区域、数据类型和指令这些部分,它们描述了JVM的一个抽象的内部体系结构,其目的不光规定实现JVM时它内部的体系结构,更重要的是提供了一种方式,用于严格定义实现时的外部行为。每个JVM都有两种机制,一个是装载具有合适名称的类(类或是接口),叫做类装载子系统;另外的一个负责执行包含在已装载的类或接口中的指令,叫做运行引擎。每个JVM又包括方法区、堆、 Java栈、程序计数器和本地方法栈这五个部分,这几个部分和类装载机制与运行引擎机制一起组成的体系结构图为:

 

图3   JVM的体系结构

JVM的每个实例都有一个它自己的方法域和一个堆,运行于JVM内的所有的线程都共享这些区域;当虚拟机装载类文件的时候,它解析其中的二进制数据所包含的类信息,并把它们放到方法域中;当程序运行的时候,JVM把程序初始化的所有对象置于堆上;而每个线程创建的时候,都会拥有自己的程序计数器和 Java栈,其中程序计数器中的值指向下一条即将被执行的指令,线程的Java栈则存储为该线程调用Java方法的状态;本地方法调用的状态被存储在本地方法栈,该方法栈依赖于具体的实现。

下面分别对这几个部分进行说明。

执行引擎处于JVM的核心位置,在Java虚拟机规范中,它的行为是由指令集所决定的。尽管对于每条指令,规范很详细地说明了当JVM执行字节码遇到指令时,它的实现应该做什么,但对于怎么做却言之甚少。Java虚拟机支持大约248个字节码。每个字节码执行一种基本的CPU运算,例如,把一个整数加到寄存器,子程序转移等。Java指令集相当于Java程序的汇编语言。

Java指令集中的指令包含一个单字节的操作符,用于指定要执行的操作,还有0个或多个操作数,提供操作所需的参数或数据。许多指令没有操作数,仅由一个单字节的操作符构成。

虚拟机的内层循环的执行过程如下:

 

do{

取一个操作符字节;

根据操作符的值执行一个动作;

}while(程序未结束)

由于指令系统的简单性,使得虚拟机执行的过程十分简单,从而有利于提高执行的效率。指令中操作数的数量和大小是由操作符决定的。如果操作数比一个字节大,那么它存储的顺序是高位字节优先。例如,一个16位的参数存放时占用两个字节,其值为:

第一个字节*256+第二个字节字节码。

指令流一般只是字节对齐的。指令tableswitch和lookup是例外,在这两条指令内部要求强制的4字节边界对齐。

对于本地方法接口,实现JVM并不要求一定要有它的支持,甚至可以完全没有。Sun公司实现Java本地接口(JNI)是出于可移植性的考虑,当然我们也可以设计出其它的本地接口来代替Sun公司的JNI。但是这些设计与实现是比较复杂的事情,需要确保垃圾回收器不会将那些正在被本地方法调用的对象释放掉。

Java的堆是一个运行时数据区,类的实例(对象)从中分配空间,它的管理是由垃圾回收来负责的:不给程序员显式释放对象的能力。Java不规定具体使用的垃圾回收算法,可以根据系统的需求使用各种各样的算法。

Java方法区与传统语言中的编译后代码或是Unix进程中的正文段类似。它保存方法代码(编译后的java代码)和符号表。在当前的Java实现中,方法代码不包括在垃圾回收堆中,但计划在将来的版本中实现。每个类文件包含了一个Java类或一个Java界面的编译后的代码。可以说类文件是 Java语言的执行代码文件。为了保证类文件的平台无关性,Java虚拟机规范中对类文件的格式也作了详细的说明。其具体细节请参考Sun公司的Java 虚拟机规范。

Java虚拟机的寄存器用于保存机器的运行状态,与微处理器中的某些专用寄存器类似。Java虚拟机的寄存器有四种:

pc: Java程序计数器; 

 

optop: 指向操作数栈顶端的指针; 

 

frame: 指向当前执行方法的执行环境的指针;。 

 

vars: 指向当前执行方法的局部变量区第一个变量的指针。 

在上述体系结构图中,我们所说的是第一种,即程序计数器,每个线程一旦被创建就拥有了自己的程序计数器。当线程执行Java方法的时候,它包含该线程正在被执行的指令的地址。但是若线程执行的是一个本地的方法,那么程序计数器的值就不会被定义。

Java虚拟机的栈有三个区域:局部变量区、运行环境区、操作数区。

局部变量区

每个Java方法使用一个固定大小的局部变量集。它们按照与vars寄存器的字偏移量来寻址。局部变量都是32位的。长整数和双精度浮点数占据了两个局部变量的空间,却按照第一个局部变量的索引来寻址。(例如,一个具有索引n的局部变量,如果是一个双精度浮点数,那么它实际占据了索引n和n+1所代表的存储空间)虚拟机规范并不要求在局部变量中的64位的值是64位对齐的。虚拟机提供了把局部变量中的值装载到操作数栈的指令,也提供了把操作数栈中的值写入局部变量的指令。

运行环境区

在运行环境中包含的信息用于动态链接,正常的方法返回以及异常捕捉。

动态链接

运行环境包括对指向当前类和当前方法的解释器符号表的指针,用于支持方法代码的动态链接。方法的class文件代码在引用要调用的方法和要访问的变量时使用符号。动态链接把符号形式的方法调用翻译成实际方法调用,装载必要的类以解释还没有定义的符号,并把变量访问翻译成与这些变量运行时的存储结构相应的偏移地址。动态链接方法和变量使得方法中使用的其它类的变化不会影响到本程序的代码。

正常的方法返回

如果当前方法正常地结束了,在执行了一条具有正确类型的返回指令时,调用的方法会得到一个返回值。执行环境在正常返回的情况下用于恢复调用者的寄存器,并把调用者的程序计数器增加一个恰当的数值,以跳过已执行过的方法调用指令,然后在调用者的执行环境中继续执行下去。

异常捕捉

异常情况在Java中被称作Error(错误)或Exception(异常),是Throwable类的子类,在程序中的原因是:①动态链接错,如无法找到所需的class文件。②运行时错,如对一个空指针的引用。程序使用了throw语句。

当异常发生时,Java虚拟机采取如下措施:

检查与当前方法相联系的catch子句表。每个catch子句包含其有效指令范围,能够处理的异常类型,以及处理异常的代码块地址。 

 

与异常相匹配的catch子句应该符合下面的条件:造成异常的指令在其指令范围之内,发生的异常类型是其能处理的异常类型的子类型。如果找到了匹配的catch子句,那么系统转移到指定的异常处理块处执行;如果没有找到异常处理块,重复寻找匹配的catch子句的过程,直到当前方法的所有嵌套的 catch子句都被检查过。 

 

由于虚拟机从第一个匹配的catch子句处继续执行,所以catch子句表中的顺序是很重要的。因为Java代码是结构化的,因此总可以把某个方法的所有的异常处理器都按序排列到一个表中,对任意可能的程序计数器的值,都可以用线性的顺序找到合适的异常处理块,以处理在该程序计数器值下发生的异常情况。 

 

如果找不到匹配的catch子句,那么当前方法得到一个"未截获异常"的结果并返回到当前方法的调用者,好像异常刚刚在其调用者中发生一样。如果在调用者中仍然没有找到相应的异常处理块,那么这种错误将被传播下去。如果错误被传播到最顶层,那么系统将调用一个缺省的异常处理块。 

操作数栈区

机器指令只从操作数栈中取操作数,对它们进行操作,并把结果返回到栈中。选择栈结构的原因是:在只有少量寄存器或非通用寄存器的机器(如 Intel486)上,也能够高效地模拟虚拟机的行为。操作数栈是32位的。它用于给方法传递参数,并从方法接收结果,也用于支持操作的参数,并保存操作的结果。例如,iadd指令将两个整数相加。相加的两个整数应该是操作数栈顶的两个字。这两个字是由先前的指令压进堆栈的。这两个整数将从堆栈弹出、相加,并把结果压回到操作数栈中。

每个原始数据类型都有专门的指令对它们进行必须的操作。每个操作数在栈中需要一个存储位置,除了long和double型,它们需要两个位置。操作数只能被适用于其类型的操作符所操作。例如,压入两个int类型的数,如果把它们当作是一个long类型的数则是非法的。在Sun的虚拟机实现中,这个限制由字节码验证器强制实行。但是,有少数操作(操作符dupe和swap),用于对运行时数据区进行操作时是不考虑类型的。

本地方法栈,当一个线程调用本地方法时,它就不再受到虚拟机关于结构和安全限制方面的约束,它既可以访问虚拟机的运行期数据区,也可以使用本地处理器以及任何类型的栈。例如,本地栈是一个C语言的栈,那么当C程序调用C函数时,函数的参数以某种顺序被压入栈,结果则返回给调用函数。在实现Java虚拟机时,本地方法接口使用的是C语言的模型栈,那么它的本地方法栈的调度与使用则完全与C语言的栈相同。

3   Java虚拟机的运行过程

上面对虚拟机的各个部分进行了比较详细的说明,下面通过一个具体的例子来分析它的运行过程。

虚拟机通过调用某个指定类的方法main启动,传递给main一个字符串数组参数,使指定的类被装载,同时链接该类所使用的其它的类型,并且初始化它们。例如对于程序:

class HelloApp

 

{

public static void main(String[] args) 

System.out.println("Hello World!"); 

for (int i = 0; i < args.length; i++ ) 

System.out.println(args[i]); 

}

编译后在命令行模式下键入: java HelloApp run virtual machine

将通过调用HelloApp的方法main来启动java虚拟机,传递给main一个包含三个字符串"run"、"virtual"、"machine"的数组。现在我们略述虚拟机在执行HelloApp时可能采取的步骤。

开始试图执行类HelloApp的main方法,发现该类并没有被装载,也就是说虚拟机当前不包含该类的二进制代表,于是虚拟机使用 ClassLoader试图寻找这样的二进制代表。如果这个进程失败,则抛出一个异常。类被装载后同时在main方法被调用之前,必须对类 HelloApp与其它类型进行链接然后初始化。链接包含三个阶段:检验,准备和解析。检验检查被装载的主类的符号和语义,准备则创建类或接口的静态域以及把这些域初始化为标准的默认值,解析负责检查主类对其它类或接口的符号引用,在这一步它是可选的。类的初始化是对类中声明的静态初始化函数和静态域的初始化构造方法的执行。一个类在初始化之前它的父类必须被初始化。整个过程如下:

 

图4:虚拟机的运行过程

4   结束语

本文通过对JVM的体系结构的深入研究以及一个Java程序执行时虚拟机的运行过程的详细分析,意在剖析清楚Java虚拟机的机理。

 



Java虚拟机(JVM)一种用于计算机设备的规范,可用不同的方式(软件或硬件)加以实现。编译虚拟机的指令集与编译微处理器的指令集非常类似。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。
 Java虚拟机(JVM)是可运行Java代码的假想计算机。只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该系统上运行。
 Java虚拟机是一个想象中的机器,在实际的计算机上通过软件模拟来实现。Java虚拟机有自己想象中的硬件,如处理器、堆栈、寄存器等,还具有相应的指令系统。

百度知道

呵呵呵

  • 瀹屾暣鏁寸悊鍏充簬JVM 鈥 JAVA铏氭嫙鏈鐨勭畝浠
    绛旓細鍫嗗尯鍩燂細瀵硅薄鍜屽疄渚嬪彉閲忕殑瀛樺偍鍦帮紝鍏变韩浜庢墍鏈夌嚎绋嬶紝浣嗛潪绾跨▼瀹夊叏锛屾槗寮曞彂StackOverflowError銆 鍫嗘爤鍖哄煙锛氱嚎绋嬬鏈夛紝瀛樺偍灞閮ㄥ彉閲忓拰鏂规硶璋冪敤锛屾墽琛屾晥鐜囬珮锛屼絾闇璀︽儠StackOverflowError銆 绋嬪簭璁℃暟鍣: 姣忎釜绾跨▼鎷ユ湁鐙珛鐨勭▼搴忚鏁板櫒锛岃褰曞綋鍓嶆寚浠ゅ湴鍧銆傚師鐢熸柟娉曞爢鏍: 涓烘敮鎸佹湰鏈烘柟娉曡屽瓨鍦紝涓烘瘡涓柊绾跨▼鍗曠嫭鍒...
  • 浠涔堟槸java铏氭嫙鏈?
    绛旓細Java铏氭嫙鏈虹敱浜斾釜閮ㄥ垎缁勬垚:涓缁勬寚浠ら泦銆佷竴缁勫瘎瀛樺櫒銆佷竴涓爤銆佷竴涓棤鐢ㄥ崟鍏冩敹闆嗗爢(Garbage-collected-heap)銆佷竴涓柟娉曞尯鍩銆傝繖浜旈儴鍒嗘槸Java铏氭嫙鏈虹殑閫昏緫鎴愪唤,涓嶄緷璧栦换浣曞疄鐜版妧鏈垨缁勭粐鏂瑰紡,浣嗗畠浠殑鍔熻兘蹇呴』鍦ㄧ湡瀹炴満鍣ㄤ笂浠ユ煇绉嶆柟寮忓疄鐜般1.Java鎸囦护闆咼ava铏氭嫙鏈烘敮鎸佸ぇ绾248涓瓧鑺傜爜銆傛瘡涓瓧鑺傜爜鎵ц涓绉嶅熀鏈殑CPU杩愮畻,...
  • 浠涔堟槸java铏氭嫙鏈,鏈変粈涔堜綔鐢?
    绛旓細Java铏氭嫙鏈猴紙JVM锛夋槸Java Virtual Machine鐨勭缉鍐欙紝瀹冩槸涓涓櫄鏋勫嚭鏉ョ殑璁$畻鏈,鏄氳繃鍦ㄥ疄闄呯殑璁$畻鏈轰笂浠跨湡妯℃嫙鍚勭璁$畻鏈哄姛鑳芥ā鎷熸潵瀹炵幇鐨銆侸ava铏氭嫙鏈烘湁鑷繁瀹屽杽鐨勭‖浠舵灦鏋,濡傚鐞嗗櫒銆佸爢鏍堛佸瘎瀛樺櫒绛,杩樺叿鏈夌浉搴旂殑鎸囦护绯荤粺銆1.涓轰粈涔堣浣跨敤Java铏氭嫙鏈 Java璇█鐨勪竴涓潪甯搁噸瑕佺殑鐗圭偣灏辨槸涓庡钩鍙扮殑鏃犲叧鎬с傝屼娇...
  • java铏氭嫙鏈鏄粈涔堟剰鎬?
    绛旓細Java铏氭嫙鏈猴紙Java Virtual Machine锛JVM锛夋槸涓绉嶅彲浠ュ湪涓嶅悓鐨勬搷浣滅郴缁熶笂杩愯Java绋嬪簭鐨勮櫄鎷熻绠楁満銆傚畠鏄湪Java骞冲彴涓嬫墍瀹氫箟鐨勪笉鍚岀▼搴忚繍琛岀殑鐜锛屼娇寰桱ava绋嬪簭鍙互瀹炵幇璺ㄥ钩鍙扮殑鐗规с侸VM鍦↗ava缂栬瘧鍣ㄥJava婧愪唬鐮佽繘琛岀紪璇戝苟鐢熸垚瀛楄妭鐮佷箣鍚庯紝灏嗚繖浜涘瓧鑺傜爜瑙i噴涓轰笉鍚屽钩鍙版満鍣ㄦ寚浠ゆ潵鎵ц銆侸VM鎻愪緵鐨勪笉姝㈡槸涓涓...
  • 浠涔堟槸java铏氭嫙鏈,绠杩板叾宸ヤ綔鏈哄埗
    绛旓細Java铏氭嫙鏈虹殑涓昏浠诲姟鏄杞絚lass鏂囦欢骞朵笖鎵ц鍏朵腑鐨勫瓧鑺傜爜銆侸ava铏氭嫙鏈哄寘鍚竴涓被瑁呰浇鍣紝瀹冨彲浠ヤ粠绋嬪簭鍜孉PI涓杞絚lass鏂囦欢銆傚瓧鑺傜爜鐢辨墽琛屽紩鎿庢潵鎵ц銆傘Java铏氭嫙鏈虹粨鏋 绫昏杞藉櫒鐨勪綋绯荤粨鏋勬槸Java铏氭嫙鏈哄湪瀹夊叏鎬у拰缃戠粶绉诲姩鎬т笂鍙戞尌閲嶈浣滅敤鐨勪竴涓柟闈紝鍥句腑鎵绀虹殑绫昏杞藉櫒鍙互鍖呭惈澶氫釜绫昏杞藉櫒鐨勫瓙绯荤粺锛 ...
  • 娣卞叆鐞嗚ВJava铏氭嫙鏈鐩綍
    绛旓細娣卞叆鐞嗚ВJava铏氭嫙鏈锛屼粠鐩綍缁撴瀯鍒版牳蹇冩満鍒 1. 鎺㈢储Java涓栫晫锛氱1绔犳杩颁簡Java鎶鏈綋绯伙紝浠庤捣婧愬埌鏈潵灞曟湜锛屽寘鎷ā鍧楀寲銆佹贩鍚堣瑷銆佸鏍稿苟琛屽拰璇硶鎵╁睍锛屼互鍙婂疄鎴樼幆鑺傦紝濡傝嚜宸辩紪璇慗DK锛岀悊瑙e唴瀛樼鐞嗙殑鍩虹銆2. 鑷姩鍐呭瓨绠$悊锛氱2绔璇︾粏瑙f瀽Java鍐呭瓨鍖哄煙锛屽寘鎷▼搴忚鏁板櫒銆佽櫄鎷熸満鏍堛佹湰鍦版柟娉曟爤绛夛紝浠ュ強鍐呭瓨...
  • 姹侸ava铏氭嫙鏈鸿瑙?
    绛旓細1 Java鎶鏈笌Java铏氭嫙鏈 璇磋捣Java,浜轰滑棣栧厛鎯冲埌鐨勬槸Java缂栫▼璇█,鐒惰屼簨瀹炰笂,Java鏄竴绉嶆妧鏈,瀹冪敱鍥涙柟闈㈢粍鎴: Java缂栫▼璇█銆丣ava绫绘枃浠舵牸寮忋丣ava铏氭嫙鏈哄拰Java搴旂敤绋嬪簭鎺ュ彛(Java API)銆傚畠浠殑鍏崇郴濡備笅鍥炬墍绀: 鍥1 Java鍥涗釜鏂归潰鐨勫叧绯 杩愯鏈熺幆澧冧唬琛ㄧ潃Java骞冲彴,寮鍙戜汉鍛樼紪鍐橨ava浠g爜(.java鏂囦欢),鐒跺悗灏嗕箣缂栬瘧鎴...
  • java铏氭嫙鏈鏈変粈涔堢敤鍛?璇锋湅鍙嬩滑缁欏皬寮熻缁嗗湴璁茶В涓涓嬨
    绛旓細Java铏氭嫙鏈鏄爤寮忕殑,瀹冧笉瀹氫箟鎴栦娇鐢ㄥ瘎瀛樺櫒鏉ヤ紶閫掓垨鎺ュ彈鍙傛暟,鍏剁洰鐨勬槸涓轰簡淇濊瘉鎸囦护闆嗙殑绠娲佹у拰瀹炵幇鏃剁殑楂樻晥鎬(鐗瑰埆鏄浜庡瘎瀛樺櫒鏁扮洰涓嶅鐨勫鐞嗗櫒)銆傛墍鏈夊瘎瀛樺櫒閮芥槸32浣嶇殑銆 鏍圝ava铏氭嫙鏈虹殑鏍堟湁涓変釜鍖哄煙:灞閮ㄥ彉閲忓尯銆佽繍琛岀幆澧冨尯銆佹搷浣滄暟鍖恒 灞閮ㄥ彉閲忓尯 姣忎釜Java鏂规硶浣跨敤涓涓浐瀹氬ぇ灏忕殑灞閮ㄥ彉閲忛泦銆傚畠浠寜鐓т笌vars...
  • 浠涔堟槸 Java 铏氭嫙鏈?
    绛旓細1.java铏氭嫙鏈瀹氫箟: 铏氭嫙鏈烘槸涓绉嶆娊璞″寲鐨勮绠楁満,閫氳繃鍦ㄥ疄闄呯殑璁$畻鏈轰笂浠跨湡妯℃嫙鍚勭璁$畻鏈哄姛鑳芥潵瀹炵幇鐨勩Java铏氭嫙鏈鏈夎嚜宸卞畬鍠勭殑纭綋鏋舵瀯,濡傚鐞嗗櫒銆佸爢鏍堛佸瘎瀛樺櫒绛,杩樺叿鏈夌浉搴旂殑鎸囦护绯荤粺銆侸ava铏氭嫙鏈哄睆钄戒簡涓...2.java铏氭嫙鏈虹殑鍩烘湰缁撴瀯
  • 铏氭嫙鏈篔ava
    绛旓細Java铏氭嫙鏈锛圝VM锛夛紝鍏ㄧО涓篔ava Virtual Machine锛屾槸涓涓櫄鎷熺殑璁$畻鏈烘灦鏋勶紝瀹冨湪瀹為檯璁$畻鏈轰笂閫氳繃妯℃嫙鍚勭纭欢鍔熻兘鏉ヨ繍琛屻侸VM鎷ユ湁鑷繁鐨勭‖浠剁粍浠讹紝濡傚鐞嗗櫒銆佸爢鏍堝拰瀵勫瓨鍣紝浠ュ強涓濂楃壒瀹氱殑鎸囦护闆嗐備娇鐢↗ava铏氭嫙鏈虹殑鍏抽敭鍦ㄤ簬Java璇█鐨勫钩鍙版棤鍏虫с傞氬父锛岄珮绾ц瑷闇瑕佹牴鎹洰鏍囧钩鍙扮紪璇戜笉鍚岀殑浠g爜銆傜劧鑰岋紝鍊熷姪...
  • 扩展阅读:虚拟机苹果版ios免费版 ... 深入java虚拟机第三版 ... java虚拟机下载手机版 ... java虚拟机apk5.0 ... java.52emu.cn ... java cms ... 虚拟机免费版下载手机 ... 安装ug12找不到java虚拟 ... 永久免费root虚拟机 ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网