forked from fuzhengwei/CodeGuide
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ca33852
commit 8f2cd6e
Showing
1,737 changed files
with
55,132 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# itstack-demo-jvm 用java实现JVM | ||
微信公众号:bugstack虫洞栈,欢迎您的关注&获取更多案例与源码!博客栈:https://bugstack.cn | ||
|
||
>JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 | ||
|
||
本专题主要介绍如何通过java代码来实现JVM的基础功能(搜索解析class文件、字节码命令、运行时数据区等),从而让java程序员通过最熟知的java程序,学习JVM是如何将java程序一步步跑起来的,按照 | ||
《java虚拟机规范》与go语言版的《自己动手写Java虚拟机》实现java版虚拟机案例如下; | ||
|
||
|
||
## 章节列表 | ||
- [用Java实现JVM第一章《命令行工具》](https://bugstack.cn/?p=59) | ||
- [用Java实现JVM第二章《搜索class文件》](https://bugstack.cn/?p=60) | ||
- [用Java实现JVM第三章《解析class文件》](https://bugstack.cn/?p=63) | ||
- [用Java实现JVM第三章《解析class文件》附[classReader拆解]](https://bugstack.cn/?p=64) | ||
- [用Java实现JVM第四章《运行时数据区》](https://bugstack.cn/?p=66) | ||
- [用Java实现JVM第五章《指令集和解释器》](https://bugstack.cn/?p=68) | ||
- [用Java实现JVM第六章《类和对象》](https://bugstack.cn/?p=69) | ||
- [用Java实现JVM第七章《方法调用和返回》](https://bugstack.cn/?p=72) | ||
- [用Java实现JVM第八章《数组和字符串》](https://bugstack.cn/?p=73) | ||
- [用Java实现JVM第九章《本地方法调用》](https://bugstack.cn/?p=74) | ||
- [用Java实现JVM第十章《异常处理》](https://bugstack.cn/?p=75) | ||
|
||
------------ | ||
|
||
## 微信公众号:bugstack虫洞栈,欢迎您的关注&获取源码! | ||
|
||
![微信公众号:bugstack虫洞栈,欢迎您的关注&获取源码!](https://bugstack.cn/wp-content/uploads/2019/08/qrcode清晰.png) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>itstack-demo-jvm</artifactId> | ||
<groupId>org.itatack.demo</groupId> | ||
<version>1.0-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>itstack-demo-jvm-01</artifactId> | ||
|
||
|
||
</project> |
50 changes: 50 additions & 0 deletions
50
src/itstack-demo-jvm/itstack-demo-jvm-01/src/main/java/org/itstack/demo/jvm/Cmd.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package org.itstack.demo.jvm; | ||
|
||
import com.beust.jcommander.JCommander; | ||
import com.beust.jcommander.Parameter; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* http://www.itstack.org | ||
* create by fuzhengwei on 2019/4/24 | ||
*/ | ||
public class Cmd { | ||
|
||
@Parameter(names = {"-?", "-help"}, description = "print help message", order = 3, help = true) | ||
boolean helpFlag = false; | ||
|
||
@Parameter(names = "-version", description = "print version and exit", order = 2) | ||
boolean versionFlag = false; | ||
|
||
@Parameter(names = {"-cp", "-classpath"}, description = "classpath", order = 1) | ||
String classpath; | ||
|
||
@Parameter(description = "main class and args") | ||
List<String> mainClassAndArgs; | ||
|
||
boolean ok; | ||
|
||
String getMainClass() { | ||
return mainClassAndArgs != null && !mainClassAndArgs.isEmpty() | ||
? mainClassAndArgs.get(0) | ||
: null; | ||
} | ||
|
||
List<String> getAppArgs() { | ||
return mainClassAndArgs != null && mainClassAndArgs.size() > 1 | ||
? mainClassAndArgs.subList(1, mainClassAndArgs.size()) | ||
: null; | ||
} | ||
|
||
static Cmd parse(String[] argv) { | ||
Cmd args = new Cmd(); | ||
JCommander cmd = JCommander.newBuilder().addObject(args).build(); | ||
cmd.parse(argv); | ||
args.ok = true; | ||
return args; | ||
} | ||
|
||
} | ||
|
||
|
27 changes: 27 additions & 0 deletions
27
src/itstack-demo-jvm/itstack-demo-jvm-01/src/main/java/org/itstack/demo/jvm/Main.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package org.itstack.demo.jvm; | ||
|
||
/** | ||
* http://www.itstack.org | ||
* create by fuzhengwei on 2019/4/24 | ||
* program arguments:-version | ||
*/ | ||
public class Main { | ||
|
||
public static void main(String[] args) { | ||
Cmd cmd = Cmd.parse(args); | ||
if (!cmd.ok || cmd.helpFlag) { | ||
System.out.println("Usage: <main class> [-options] class [args...]"); | ||
return; | ||
} | ||
if (cmd.versionFlag) { | ||
System.out.println("java version \"1.8.0\""); | ||
return; | ||
} | ||
startJVM(cmd); | ||
} | ||
|
||
private static void startJVM(Cmd cmd) { | ||
System.out.printf("classpath:%s class:%s args:%s\n", cmd.classpath, cmd.getMainClass(), cmd.getAppArgs()); | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
src/itstack-demo-jvm/itstack-demo-jvm-01/src/test/java/org/itstack/demo/test/HelloWorld.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.itstack.demo.test; | ||
|
||
public class HelloWorld { | ||
|
||
public static void main(String[] args) { | ||
System.out.println("hello world"); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>itstack-demo-jvm</artifactId> | ||
<groupId>org.itatack.demo</groupId> | ||
<version>1.0-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>itstack-demo-jvm-02</artifactId> | ||
|
||
|
||
</project> |
53 changes: 53 additions & 0 deletions
53
src/itstack-demo-jvm/itstack-demo-jvm-02/src/main/java/org/itstack/demo/jvm/Cmd.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package org.itstack.demo.jvm; | ||
|
||
import com.beust.jcommander.JCommander; | ||
import com.beust.jcommander.Parameter; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* http://www.itstack.org | ||
* create by fuzhengwei on 2019/4/24 | ||
*/ | ||
public class Cmd { | ||
|
||
@Parameter(names = {"-?", "-help"}, description = "print help message", order = 3, help = true) | ||
boolean helpFlag = false; | ||
|
||
@Parameter(names = "-version", description = "print version and exit", order = 2) | ||
boolean versionFlag = false; | ||
|
||
@Parameter(names = {"-cp", "-classpath"}, description = "classpath", order = 1) | ||
String classpath; | ||
|
||
@Parameter(names = "-Xjre", description = "path to jre", order = 4) | ||
String jre; | ||
|
||
@Parameter(description = "main class and args") | ||
List<String> mainClassAndArgs; | ||
|
||
boolean ok; | ||
|
||
String getMainClass() { | ||
return mainClassAndArgs != null && !mainClassAndArgs.isEmpty() | ||
? mainClassAndArgs.get(0) | ||
: null; | ||
} | ||
|
||
List<String> getAppArgs() { | ||
return mainClassAndArgs != null && mainClassAndArgs.size() > 1 | ||
? mainClassAndArgs.subList(1, mainClassAndArgs.size()) | ||
: null; | ||
} | ||
|
||
static Cmd parse(String[] argv) { | ||
Cmd args = new Cmd(); | ||
JCommander cmd = JCommander.newBuilder().addObject(args).build(); | ||
cmd.parse(argv); | ||
args.ok = true; | ||
return args; | ||
} | ||
|
||
} | ||
|
||
|
49 changes: 49 additions & 0 deletions
49
src/itstack-demo-jvm/itstack-demo-jvm-02/src/main/java/org/itstack/demo/jvm/Main.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package org.itstack.demo.jvm; | ||
|
||
import org.itstack.demo.jvm.classpath.Classpath; | ||
|
||
import java.util.Arrays; | ||
|
||
/** | ||
* http://www.itstack.org | ||
* create by fuzhengwei on 2019/4/24 | ||
* program arguments:-Xjre "C:\Program Files\Java\jdk1.8.0_161\jre" E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-02\target\test-classes\org\itstack\demo\test\HelloWorld | ||
*/ | ||
public class Main { | ||
|
||
public static void main(String[] args) { | ||
Cmd cmd = Cmd.parse(args); | ||
if (!cmd.ok || cmd.helpFlag) { | ||
System.out.println("Usage: <main class> [-options] class [args...]"); | ||
return; | ||
} | ||
if (cmd.versionFlag) { | ||
//注意案例测试都是基于1.8,另外jdk1.9以后使用模块化没有rt.jar | ||
System.out.println("java version \"1.8.0\""); | ||
return; | ||
} | ||
startJVM(cmd); | ||
} | ||
|
||
private static void startJVM(Cmd cmd) { | ||
Classpath cp = new Classpath(cmd.jre, cmd.classpath); | ||
System.out.printf("classpath:%s class:%s args:%s\n", cp, cmd.getMainClass(), cmd.getAppArgs()); | ||
//获取className | ||
String className = cmd.getMainClass().replace(".", "/"); | ||
try { | ||
byte[] classData = cp.readClass(className); | ||
|
||
System.out.println(Arrays.toString(classData)); | ||
|
||
System.out.println("classData:"); | ||
// for (byte b : classData) { | ||
// //16进制输出 | ||
// System.out.print(String.format("%02x", b & 0xff) + " "); | ||
// } | ||
} catch (Exception e) { | ||
System.out.println("Could not find or load main class " + cmd.getMainClass()); | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
} |
83 changes: 83 additions & 0 deletions
83
...-demo-jvm/itstack-demo-jvm-02/src/main/java/org/itstack/demo/jvm/classpath/Classpath.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package org.itstack.demo.jvm.classpath; | ||
|
||
import org.itstack.demo.jvm.classpath.impl.WildcardEntry; | ||
|
||
import java.io.File; | ||
import java.nio.file.Files; | ||
import java.nio.file.Paths; | ||
|
||
/** | ||
* http://www.itstack.org | ||
* create by fuzhengwei on 2019/4/24 | ||
* 类路径 | ||
*/ | ||
public class Classpath { | ||
|
||
private Entry bootstrapClasspath; //启动类路径 | ||
private Entry extensionClasspath; //扩展类路径 | ||
private Entry userClasspath; //用户类路径 | ||
|
||
public Classpath(String jreOption, String cpOption) { | ||
//启动类&扩展类 "C:\Program Files\Java\jdk1.8.0_161\jre" | ||
bootstrapAndExtensionClasspath(jreOption); | ||
//用户类 E:\..\org\itstack\demo\test\HelloWorld | ||
parseUserClasspath(cpOption); | ||
} | ||
|
||
private void bootstrapAndExtensionClasspath(String jreOption) { | ||
|
||
String jreDir = getJreDir(jreOption); | ||
|
||
//..jre/lib/* | ||
String jreLibPath = Paths.get(jreDir, "lib") + File.separator + "*"; | ||
bootstrapClasspath = new WildcardEntry(jreLibPath); | ||
|
||
//..jre/lib/ext/* | ||
String jreExtPath = Paths.get(jreDir, "lib", "ext") + File.separator + "*"; | ||
extensionClasspath = new WildcardEntry(jreExtPath); | ||
|
||
} | ||
|
||
private static String getJreDir(String jreOption) { | ||
if (jreOption != null && Files.exists(Paths.get(jreOption))) { | ||
return jreOption; | ||
} | ||
if (Files.exists(Paths.get("./jre"))) { | ||
return "./jre"; | ||
} | ||
String jh = System.getenv("JAVA_HOME"); | ||
if (jh != null) { | ||
return Paths.get(jh, "jre").toString(); | ||
} | ||
throw new RuntimeException("Can not find JRE folder!"); | ||
} | ||
|
||
private void parseUserClasspath(String cpOption) { | ||
if (cpOption == null) { | ||
cpOption = "."; | ||
} | ||
userClasspath = Entry.create(cpOption); | ||
} | ||
|
||
public byte[] readClass(String className) throws Exception { | ||
className = className + ".class"; | ||
|
||
//[readClass]启动类路径 | ||
try { | ||
return bootstrapClasspath.readClass(className); | ||
} catch (Exception ignored) { | ||
//ignored | ||
} | ||
|
||
//[readClass]扩展类路径 | ||
try { | ||
return extensionClasspath.readClass(className); | ||
} catch (Exception ignored) { | ||
//ignored | ||
} | ||
|
||
//[readClass]用户类路径 | ||
return userClasspath.readClass(className); | ||
} | ||
|
||
} |
39 changes: 39 additions & 0 deletions
39
...tack-demo-jvm/itstack-demo-jvm-02/src/main/java/org/itstack/demo/jvm/classpath/Entry.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package org.itstack.demo.jvm.classpath; | ||
|
||
import org.itstack.demo.jvm.classpath.impl.CompositeEntry; | ||
import org.itstack.demo.jvm.classpath.impl.DirEntry; | ||
import org.itstack.demo.jvm.classpath.impl.WildcardEntry; | ||
import org.itstack.demo.jvm.classpath.impl.ZipEntry; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
|
||
/** | ||
* http://www.itstack.org | ||
* create by fuzhengwei on 2019/4/24 | ||
* 类路径接口 | ||
*/ | ||
public interface Entry { | ||
|
||
byte[] readClass(String className) throws IOException; | ||
|
||
static Entry create(String path) { | ||
|
||
//File.pathSeparator;路径分隔符(win\linux) | ||
if (path.contains(File.pathSeparator)) { | ||
return new CompositeEntry(path); | ||
} | ||
|
||
if (path.endsWith("*")) { | ||
return new WildcardEntry(path); | ||
} | ||
|
||
if (path.endsWith(".jar") || path.endsWith(".JAR") || | ||
path.endsWith(".zip") || path.endsWith(".ZIP")) { | ||
return new ZipEntry(path); | ||
} | ||
|
||
return new DirEntry(path); | ||
} | ||
|
||
} |
Oops, something went wrong.