();
19 | // 10MB的PermSize在integer范围内足够产生OOM了
20 | int i = 0;
21 | while (true) {
22 | list.add(String.valueOf(i++).intern());
23 | }
24 | }
25 | }
26 |
27 |
28 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch2/RuntimeConstantPoolOOM2.java:
--------------------------------------------------------------------------------
1 | package ch2;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class RuntimeConstantPoolOOM2 {
7 |
8 | public static void main(String[] args) {
9 |
10 | String str1 = new StringBuilder("中国").append("钓鱼岛").toString();
11 | System.out.println(str1.intern() == str1);
12 |
13 | String str2 = new StringBuilder("ja").append("va").toString();
14 | System.out.println(str2.intern() == str2);
15 | }
16 | }
17 |
18 |
19 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch3/FinalizeEscapeGC.java:
--------------------------------------------------------------------------------
1 | package ch3;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | /**
7 | * 此代码演示了两点:
8 | * 1.对象可以在被GC时自我拯救。
9 | * 2.这种自救的机会只有一次,因为一个对象的finalize()方法最多只会被系统自动调用一次
10 | * @author zzm
11 | */
12 | public class FinalizeEscapeGC {
13 |
14 | public static FinalizeEscapeGC SAVE_HOOK = null;
15 |
16 | public void isAlive() {
17 | System.out.println("yes, i am still alive :)");
18 | }
19 |
20 | @Override
21 | protected void finalize() throws Throwable {
22 | super.finalize();
23 | System.out.println("finalize mehtod executed!");
24 | FinalizeEscapeGC.SAVE_HOOK = this;
25 | }
26 |
27 | public static void main(String[] args) throws Throwable {
28 | SAVE_HOOK = new FinalizeEscapeGC();
29 |
30 | //对象第一次成功拯救自己
31 | SAVE_HOOK = null;
32 | System.gc();
33 | // 因为Finalizer方法优先级很低,暂停0.5秒,以等待它
34 | Thread.sleep(500);
35 | if (SAVE_HOOK != null) {
36 | SAVE_HOOK.isAlive();
37 | } else {
38 | System.out.println("no, i am dead :(");
39 | }
40 |
41 | // 下面这段代码与上面的完全相同,但是这次自救却失败了
42 | SAVE_HOOK = null;
43 | System.gc();
44 | // 因为Finalizer方法优先级很低,暂停0.5秒,以等待它
45 | Thread.sleep(500);
46 | if (SAVE_HOOK != null) {
47 | SAVE_HOOK.isAlive();
48 | } else {
49 | System.out.println("no, i am dead :(");
50 | }
51 | }
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch3/ReferenceCountingGC.java:
--------------------------------------------------------------------------------
1 | package ch3;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | /**
7 | * testGC()方法执行后,objA和objB会不会被GC呢?
8 | * @author zzm
9 | */
10 | public class ReferenceCountingGC {
11 |
12 | public Object instance = null;
13 |
14 | private static final int _1MB = 1024 * 1024;
15 |
16 | /**
17 | * 这个成员属性的唯一意义就是占点内存,以便在能在GC日志中看清楚是否有回收过
18 | */
19 | private byte[] bigSize = new byte[2 * _1MB];
20 |
21 | public static void testGC() {
22 | ReferenceCountingGC objA = new ReferenceCountingGC();
23 | ReferenceCountingGC objB = new ReferenceCountingGC();
24 | objA.instance = objB;
25 | objB.instance = objA;
26 |
27 | objA = null;
28 | objB = null;
29 |
30 | // 假设在这行发生GC,objA和objB是否能被回收?
31 | System.gc();
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch3/Test35.java:
--------------------------------------------------------------------------------
1 | package ch3;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test35 {
7 | private static final int _1MB = 1024 * 1024;
8 |
9 | /**
10 | * VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
11 | */
12 | public static void testAllocation() {
13 | byte[] allocation1, allocation2, allocation3, allocation4;
14 | allocation1 = new byte[2 * _1MB];
15 | allocation2 = new byte[2 * _1MB];
16 | allocation3 = new byte[2 * _1MB];
17 | allocation4 = new byte[4 * _1MB]; // 出现一次Minor GC
18 | }
19 |
20 | public static void main(String[] args) {
21 | //老年代 10M 年轻代 10M 8M eden 1M from 1M to
22 | //allocation1,allocation2,allocation3在eden区分配,但是allocation4在old区分配,
23 | testAllocation();
24 | }
25 |
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch3/Test36.java:
--------------------------------------------------------------------------------
1 | package ch3;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test36 {
7 | private static final int _1MB = 1024 * 1024;
8 |
9 | /**
10 | * VM参数:-XX:+UseSerialGC -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728
11 | */
12 | public static void testPretenureSizeThreshold() {
13 | byte[] allocation;
14 | allocation = new byte[4 * _1MB]; //直接分配在老年代中
15 | }
16 |
17 | public static void main(String[] args) {
18 | testPretenureSizeThreshold();
19 | }
20 |
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch3/Test37.java:
--------------------------------------------------------------------------------
1 | package ch3;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test37 {
7 | private static final int _1MB = 1024 * 1024;
8 |
9 | /**
10 | * VM参数:-XX:+UseSerialGC -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=1
11 | * -XX:+PrintTenuringDistribution
12 | */
13 | @SuppressWarnings("unused")
14 | public static void testTenuringThreshold() {
15 | byte[] allocation1, allocation2, allocation3;
16 | allocation1 = new byte[_1MB / 4]; // 什么时候进入老年代决定于XX:MaxTenuringThreshold设置
17 | allocation2 = new byte[4 * _1MB];
18 | allocation3 = new byte[4 * _1MB];
19 | allocation3 = null;
20 | allocation3 = new byte[4 * _1MB];
21 | }
22 |
23 | public static void main(String[] args) {
24 | testTenuringThreshold();
25 | }
26 |
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch3/Test38.java:
--------------------------------------------------------------------------------
1 | package ch3;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test38 {
7 | private static final int _1MB = 1024 * 1024;
8 |
9 | /**
10 | * VM参数: -XX:+UseSerialGC -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15
11 | * -XX:+PrintTenuringDistribution
12 | */
13 | @SuppressWarnings("unused")
14 | public static void testTenuringThreshold2() {
15 | byte[] allocation1, allocation2, allocation3, allocation4;
16 | allocation1 = new byte[_1MB / 4]; // allocation1+allocation2大于survivo空间一半
17 | allocation2 = new byte[_1MB / 4];
18 | allocation3 = new byte[4 * _1MB];
19 | allocation4 = new byte[4 * _1MB];
20 | allocation4 = null;
21 | allocation4 = new byte[4 * _1MB];
22 | }
23 |
24 | public static void main(String[] args) {
25 | testTenuringThreshold2();
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch3/Test39.java:
--------------------------------------------------------------------------------
1 | package ch3;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test39 {
7 | private static final int _1MB = 1024 * 1024;
8 |
9 | /**
10 | * VM参数:-Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:-HandlePromotionFailure
11 | */
12 | @SuppressWarnings("unused")
13 | public static void testHandlePromotion() {
14 | byte[] allocation1, allocation2, allocation3, allocation4, allocation5, allocation6, allocation7;
15 | allocation1 = new byte[2 * _1MB];
16 | allocation2 = new byte[2 * _1MB];
17 | allocation3 = new byte[2 * _1MB];
18 | allocation1 = null;
19 | allocation4 = new byte[2 * _1MB];
20 | allocation5 = new byte[2 * _1MB];
21 | allocation6 = new byte[2 * _1MB];
22 | allocation4 = null;
23 | allocation5 = null;
24 | allocation6 = null;
25 | allocation7 = new byte[2 * _1MB];
26 | }
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch4/BTraceTest.java:
--------------------------------------------------------------------------------
1 | package ch4;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 |
7 | /**
8 | * Created by lili on 2017/7/16.
9 | */
10 | public class BTraceTest {
11 |
12 | public int add(int a, int b) {
13 | return a + b;
14 | }
15 |
16 | public static void main(String[] args) throws IOException {
17 | BTraceTest test = new BTraceTest();
18 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
19 | for (int i = 0; i < 10; i++) {
20 | reader.readLine();
21 | int a = (int) Math.round(Math.random() * 1000);
22 | int b = (int) Math.round(Math.random() * 1000);
23 | System.out.println(test.add(a, b));
24 | }
25 | }
26 | }
27 |
28 |
29 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch4/Bar.java:
--------------------------------------------------------------------------------
1 | package ch4;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Bar {
7 | int a = 1;
8 | static int b = 2;
9 |
10 | public int sum(int c) {
11 | return a + b + c;
12 | }
13 |
14 | public static void main(String[] args) {
15 | new Bar().sum(3);
16 | }
17 | }
18 |
19 |
20 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch4/Test410.java:
--------------------------------------------------------------------------------
1 | package ch4;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test410 {
7 | /**
8 | * 线程死锁等待演示
9 | */
10 | static class SynAddRunalbe implements Runnable {
11 | int a, b;
12 | public SynAddRunalbe(int a, int b) {
13 | this.a = a;
14 | this.b = b;
15 | }
16 |
17 | public void run() {
18 | synchronized (Integer.valueOf(a)) {
19 | synchronized (Integer.valueOf(b)) {
20 | System.out.println(a + b);
21 | }
22 | }
23 | }
24 | }
25 |
26 | public static void main(String[] args) {
27 | for (int i = 0; i < 100; i++) {
28 | new Thread(new SynAddRunalbe(1, 2)).start();
29 | new Thread(new SynAddRunalbe(2, 1)).start();
30 | }
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch4/Test45.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.util.Map"%>
2 |
3 |
4 |
5 | 服务器线程信息
6 |
7 |
8 |
9 | <%
10 | for (Map.Entry stackTrace : Thread.getAllStackTraces().entrySet()) {
11 | Thread thread = (Thread) stackTrace.getKey();
12 | StackTraceElement[] stack = (StackTraceElement[]) stackTrace.getValue();
13 | if (thread.equals(Thread.currentThread())) {
14 | continue;
15 | }
16 | out.print("\n线程:" + thread.getName() + "\n");
17 | for (StackTraceElement element : stack) {
18 | out.print("\t"+element+"\n");
19 | }
20 | }
21 | %>
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch4/Test48.java:
--------------------------------------------------------------------------------
1 | package ch4;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by lili on 2017/7/16.
8 | */
9 | public class Test48 {
10 | /**
11 | * 内存占位符对象,一个OOMObject大约占64K
12 | */
13 | static class OOMObject {
14 | public byte[] placeholder = new byte[64 * 1024];
15 | }
16 |
17 | public static void fillHeap(int num) throws InterruptedException {
18 | List list = new ArrayList();
19 | for (int i = 0; i < num; i++) {
20 | // 稍作延时,令监视曲线的变化更加明显
21 | Thread.sleep(50);
22 | list.add(new OOMObject());
23 | }
24 | System.gc();
25 | }
26 |
27 | public static void main(String[] args) throws Exception {
28 | fillHeap(1000);
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch4/Test49.java:
--------------------------------------------------------------------------------
1 | package ch4;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.InputStreamReader;
5 |
6 | /**
7 | * Created by lili on 2017/7/16.
8 | */
9 | public class Test49 {
10 | /**
11 | * 线程死循环演示
12 | */
13 | public static void createBusyThread() {
14 | Thread thread = new Thread(new Runnable() {
15 | public void run() {
16 | while (true) // 第41行
17 | ;
18 | }
19 | }, "testBusyThread");
20 | thread.start();
21 | }
22 |
23 | /**
24 | * 线程锁等待演示
25 | */
26 | public static void createLockThread(final Object lock) {
27 | Thread thread = new Thread(new Runnable() {
28 | public void run() {
29 | synchronized (lock) {
30 | try {
31 | lock.wait();
32 | } catch (InterruptedException e) {
33 | e.printStackTrace();
34 | }
35 | }
36 | }
37 | }, "testLockThread");
38 | thread.start();
39 | }
40 |
41 | public static void main(String[] args) throws Exception {
42 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
43 | br.readLine();
44 | createBusyThread();
45 | br.readLine();
46 | Object obj = new Object();
47 | createLockThread(obj);
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch4/TracingScript .java:
--------------------------------------------------------------------------------
1 | package ch4;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | /* BTrace Script Template */
7 | /*
8 | import com.sun.btrace.annotations.*;
9 | import static com.sun.btrace.BTraceUtils.*;
10 | import static sun.plugin.javascript.navig.JSType.Location;
11 |
12 | @BTrace
13 | public class TracingScript {
14 | @OnMethod(
15 | clazz="org.fenixsoft.monitoring.BTraceTest",
16 | method="add",
17 | location=@Location(Kind.RETURN)
18 | )
19 |
20 | public static void func(@Self org.fenixsoft.monitoring.BTraceTest instance,int a,int b,@Return int result) {
21 | println("调用堆栈:");
22 | jstack();
23 | println(strcat("方法参数A:",str(a)));
24 | println(strcat("方法参数B:",str(b)));
25 | println(strcat("方法结果:",str(result)));
26 | }
27 | }
28 | */
29 |
30 |
31 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch5/EclipseStartTime_1.0.0.201011281102.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/understandingjvm/src/main/java/ch5/EclipseStartTime_1.0.0.201011281102.jar
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch6/GetSignature.java:
--------------------------------------------------------------------------------
1 | package ch6;
2 |
3 | import java.lang.reflect.ParameterizedType;
4 | import java.lang.reflect.Type;
5 | import java.util.Arrays;
6 |
7 | /**
8 | * @packgeName: ch6
9 | * @ClassName: GetSignature
10 | * @copyright: CopyLeft
11 | * @description:<描述>
12 | * @author: lili
13 | * @date: 2017/10/14-16:45
14 | * @version: 1.0
15 | * @since: JDK 1.8
16 | */
17 | public class GetSignature {
18 | public static void main(String[] args) throws ClassNotFoundException {
19 |
20 | Class c = Class.forName("java.lang.String");
21 | System.out.println(c);
22 | Type[] t = c.getGenericInterfaces();
23 | System.out.println(t);
24 | for (Type type : t) {
25 | if (type instanceof ParameterizedType) {
26 | // System.out.println("in if");
27 | Type[] p = ((ParameterizedType) type).getActualTypeArguments();
28 | System.out.println(Arrays.toString(p));
29 | // this.clazz = (Class) p[0];
30 | }
31 | }
32 |
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch6/OnlyMe.java:
--------------------------------------------------------------------------------
1 | package ch6;
2 |
3 | /**
4 | * @packgeName: ch6
5 | * @ClassName: OnlyMe
6 | * @copyright: CopyLeft
7 | * @description:<描述>
8 | * @author: lili
9 | * @date: 2017/10/14-16:58
10 | * @version: 1.0
11 | * @since: JDK 1.8
12 | */
13 | class Foo{}
14 |
15 | public class OnlyMe {
16 | void onlyme(Foo f){
17 | synchronized (f){
18 | System.out.println("do something ");
19 | }
20 | }
21 |
22 | synchronized void onlyme2(){
23 | System.out.println("do something else");
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch6/TestClass.java:
--------------------------------------------------------------------------------
1 | package ch6;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | public class TestClass {
8 |
9 | private int m;
10 |
11 | public int inc() {
12 | return m + 1;
13 | }
14 | }
15 |
16 |
17 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch7/ClassLoaderTest.java:
--------------------------------------------------------------------------------
1 | package ch7;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 |
10 | /**
11 | * 类加载器与instanceof关键字演示
12 | *
13 | * @author zzm
14 | */
15 | public class ClassLoaderTest {
16 |
17 | public static void main(String[] args) throws IOException {
18 |
19 | ClassLoader myLoader = new ClassLoader() {
20 | @Override
21 | public Class> loadClass(String name) throws ClassNotFoundException {
22 | try {
23 | String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
24 | InputStream is = getClass().getResourceAsStream(fileName);
25 | if (is == null) {
26 | return super.loadClass(name);
27 | }
28 | byte[] b = new byte[is.available()];
29 | is.read(b);
30 | return defineClass(name, b, 0, b.length);
31 | } catch (IOException e) {
32 | throw new ClassNotFoundException(name);
33 | }
34 | }
35 | };
36 |
37 | Object obj = null;
38 | try {
39 | obj = myLoader.loadClass("org.fenixsoft.classloading.ClassLoaderTest").newInstance();
40 | } catch (InstantiationException e) {
41 | e.printStackTrace();
42 | } catch (IllegalAccessException e) {
43 | e.printStackTrace();
44 | } catch (ClassNotFoundException e) {
45 | e.printStackTrace();
46 | }
47 |
48 | System.out.println(obj.getClass());
49 | System.out.println(obj instanceof ClassLoaderTest);
50 | }
51 | }
52 |
53 |
54 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch7/FieldResolution.java:
--------------------------------------------------------------------------------
1 | package ch7;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | public class FieldResolution {
8 |
9 | interface Interface0 {
10 | int A = 0;
11 | }
12 |
13 | interface Interface1 extends Interface0 {
14 | int A = 1;
15 | }
16 |
17 | interface Interface2 {
18 | int A = 2;
19 | }
20 |
21 | static class Parent implements Interface1 {
22 | public static int A = 3;
23 | }
24 |
25 | static class Sub extends Parent implements Interface2 {
26 | public static int A = 4;
27 | }
28 |
29 | public static void main(String[] args) {
30 | System.out.println(Sub.A);
31 | }
32 | }
33 |
34 |
35 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch7/NotInitialization2.java:
--------------------------------------------------------------------------------
1 | package ch7;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | /**
8 | * 被动使用类字段演示二:
9 | * 通过数组定义来引用类,不会触发此类的初始化
10 | **/
11 | public class NotInitialization2 {
12 |
13 | public static void main(String[] args) {
14 | SuperClass[] sca = new SuperClass[10];
15 | }
16 |
17 | }
18 |
19 |
20 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch7/NotInitialization3.java:
--------------------------------------------------------------------------------
1 | package ch7;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | /**
8 | * 被动使用类字段演示三:
9 | * 常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。
10 | **/
11 | class ConstClass {
12 |
13 | static {
14 | System.out.println("ConstClass init!");
15 | }
16 |
17 | public static final String HELLOWORLD = "hello world";
18 | }
19 |
20 | /**
21 | * 非主动使用类字段演示
22 | **/
23 | public class NotInitialization3 {
24 |
25 | public static void main(String[] args) {
26 | System.out.println(ConstClass.HELLOWORLD);
27 | }
28 | }
29 |
30 |
31 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch7/SuperClass.java:
--------------------------------------------------------------------------------
1 | package ch7;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | /**
8 | * 被动使用类字段演示一:
9 | * 通过子类引用父类的静态字段,不会导致子类初始化
10 | **/
11 | public class SuperClass {
12 |
13 | static {
14 | System.out.println("SuperClass init!");
15 | }
16 |
17 | public static int value = 123;
18 | }
19 |
20 | class SubClass extends SuperClass {
21 |
22 | static {
23 | System.out.println("SubClass init!");
24 | }
25 | }
26 |
27 | /**
28 | * 非主动使用类字段演示
29 | **/
30 | class NotInitialization {
31 |
32 | public static void main(String[] args) {
33 | System.out.println(SubClass.value);
34 | }
35 |
36 | }
37 |
38 |
39 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch7/Test.java:
--------------------------------------------------------------------------------
1 | package ch7;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test {
7 | static {
8 | i = 0; // 给变量复制可以正常编译通过
9 | //System.out.print(i); // 这句编译器会提示“非法向前引用”
10 | }
11 | static int i = 1;
12 | }
13 |
14 |
15 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch7/Test76.java:
--------------------------------------------------------------------------------
1 | package ch7;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test76 {
7 | static class Parent {
8 | public static int A = 1;
9 | static {
10 | A = 2;
11 | }
12 | }
13 |
14 | static class Sub extends Parent {
15 | public static int B = A;
16 | }
17 |
18 | public static void main(String[] args) {
19 | System.out.println(Sub.B);
20 | }
21 |
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch7/Test77.java:
--------------------------------------------------------------------------------
1 | package ch7;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test77 {
7 | static class DeadLoopClass {
8 | static {
9 | // 如果不加上这个if语句,编译器将提示“Initializer does not complete normally”并拒绝编译
10 | if (true) {
11 | System.out.println(Thread.currentThread() + "init DeadLoopClass");
12 | while (true) {
13 | }
14 | }
15 | }
16 | }
17 |
18 | public static void main(String[] args) {
19 | Runnable script = new Runnable() {
20 | public void run() {
21 | System.out.println(Thread.currentThread() + "start");
22 | DeadLoopClass dlc = new DeadLoopClass();
23 | System.out.println(Thread.currentThread() + " run over");
24 | }
25 | };
26 |
27 | Thread thread1 = new Thread(script);
28 | Thread thread2 = new Thread(script);
29 | thread1.start();
30 | thread2.start();
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/Dispatch.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | /**
8 | * 单分派、多分派演示
9 | *
10 | * @author zzm
11 | */
12 | public class Dispatch {
13 |
14 | static class QQ {
15 | }
16 |
17 | static class _360 {
18 | }
19 |
20 | public static class Father {
21 | public void hardChoice(QQ arg) {
22 | System.out.println("father choose qq");
23 | }
24 |
25 | public void hardChoice(_360 arg) {
26 | System.out.println("father choose 360");
27 | }
28 | }
29 |
30 | public static class Son extends Father {
31 | public void hardChoice(QQ arg) {
32 | System.out.println("son choose qq");
33 | }
34 |
35 | public void hardChoice(_360 arg) {
36 | System.out.println("son choose 360");
37 | }
38 | }
39 |
40 | public static void main(String[] args) throws InterruptedException {
41 | Father father = new Father();
42 | Father son = new Son();
43 | father.hardChoice(new _360());
44 | son.hardChoice(new QQ());
45 | }
46 | }
47 |
48 |
49 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/DynamicDispatch.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | /**
8 | * 方法动态分派演示
9 | *
10 | * @author zzm
11 | */
12 | public class DynamicDispatch {
13 |
14 | static abstract class Human {
15 | protected abstract void sayHello();
16 | }
17 |
18 | static class Man extends Human {
19 | @Override
20 | protected void sayHello() {
21 | System.out.println("man say hello");
22 | }
23 | }
24 |
25 | static class Woman extends Human {
26 | @Override
27 | protected void sayHello() {
28 | System.out.println("woman say hello");
29 | }
30 | }
31 |
32 | public static void main(String[] args) {
33 | Human man = new Man();
34 | Human woman = new Woman();
35 | man.sayHello();
36 | woman.sayHello();
37 | man = new Woman();
38 | man.sayHello();
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/InvokeDynamicTest.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | import java.lang.invoke.*;
7 |
8 | import static java.lang.invoke.MethodHandles.lookup;
9 |
10 | public class InvokeDynamicTest {
11 |
12 | public static void main(String[] args) throws Throwable {
13 | INDY_BootstrapMethod().invokeExact("icyfenix");
14 | }
15 |
16 | public static void testMethod(String s) {
17 | System.out.println("hello String:" + s);
18 | }
19 |
20 | public static CallSite BootstrapMethod(MethodHandles.Lookup lookup, String name, MethodType mt) throws Throwable {
21 | return new ConstantCallSite(lookup.findStatic(InvokeDynamicTest.class, name, mt));
22 | }
23 |
24 | private static MethodType MT_BootstrapMethod() {
25 | return MethodType
26 | .fromMethodDescriptorString(
27 | "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
28 | null);
29 | }
30 |
31 | private static MethodHandle MH_BootstrapMethod() throws Throwable {
32 | return lookup().findStatic(InvokeDynamicTest.class, "BootstrapMethod", MT_BootstrapMethod());
33 | }
34 |
35 | private static MethodHandle INDY_BootstrapMethod() throws Throwable {
36 | CallSite cs = (CallSite) MH_BootstrapMethod().invokeWithArguments(lookup(), "testMethod",
37 | MethodType.fromMethodDescriptorString("(Ljava/lang/String;)V", null));
38 | return cs.dynamicInvoker();
39 | }
40 | }
41 |
42 |
43 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/MethodHandleTest.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | import java.lang.invoke.MethodHandle;
8 | import java.lang.invoke.MethodType;
9 |
10 | import static java.lang.invoke.MethodHandles.lookup;
11 |
12 | /**
13 | * JSR 292 MethodHandle基础用法演示
14 | *
15 | * @author zzm
16 | */
17 | public class MethodHandleTest {
18 |
19 | static class ClassA {
20 | public void println(String s) {
21 | System.out.println(s);
22 | }
23 | }
24 |
25 | public static void main(String[] args) throws Throwable {
26 | Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA();
27 | // 无论obj最终是哪个实现类,下面这句都能正确调用到println方法。
28 | getPrintlnMH(obj).invokeExact("icyfenix");
29 |
30 |
31 | // ClassA a = new ClassA();
32 | // a.println("2");
33 | }
34 |
35 | private static MethodHandle getPrintlnMH(Object reveiver) throws Throwable {
36 | // MethodType:代表“方法类型”,包含了方法的返回值(methodType()的第一个参数)
37 | // 和具体参数(methodType()第二个及以后的参数)。
38 | MethodType mt = MethodType.methodType(void.class, String.class);
39 | // lookup()方法来自于MethodHandles.lookup,这句的作用是在指定类中查找符合给定的
40 | // 方法名称、方法类型,并且符合调用权限的方法句柄。
41 | // 因为这里调用的是一个虚方法,按照Java语言的规则,方法第一个参数是隐式的,代表该方
42 | // 法的接收者,也即是this指向的对象,这个参数以前是放在参数列表中进行传递,现在提供了
43 | // bindTo()方法来完成这件事情。
44 | return lookup().findVirtual(reveiver.getClass(), "println", mt).bindTo(reveiver);
45 | }
46 | }
47 |
48 |
49 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/Overload.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | public class Overload {
8 |
9 | // public static void sayHello(Object arg) {
10 | // System.out.println("hello Object");
11 | // }
12 |
13 | // public static void sayHello(int arg) {
14 | // System.out.println("hello int");
15 | // }
16 |
17 | // public static void sayHello(long arg) {
18 | // System.out.println("hello long");
19 | // }
20 |
21 | // public static void sayHello(Character arg) {
22 | // System.out.println("hello Character");
23 | // }
24 |
25 | // public static void sayHello(char arg) {
26 | // System.out.println("hello char");
27 | // }
28 |
29 | public static void sayHello(char... arg) {
30 | System.out.println("hello char ...");
31 | }
32 |
33 | // public static void sayHello(Serializable arg) {
34 | // System.out.println("hello Serializable");
35 | // }
36 |
37 | public static void main(String[] args) {
38 | sayHello('a');
39 | }
40 | }
41 |
42 |
43 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/SonTest.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * @packgeName: ch8
5 | * @ClassName: SonTest
6 | * @copyright: CopyLeft
7 | * @description:<描述>
8 | * @author: lili
9 | * @date: 2017/10/14-12:31
10 | * @version: 1.0
11 | * @since: JDK 1.8
12 | */
13 | class GrandFather{
14 | void thinking(){
15 | System.out.println("I am a grandfather");
16 | }
17 | }
18 |
19 | class Father extends GrandFather{
20 | void thinking(){
21 | System.out.println("I am a father");
22 | }
23 | }
24 |
25 | class Son extends Father{
26 | void thinking(){
27 | GrandFather father = new GrandFather();
28 | father.thinking();
29 | }
30 | }
31 |
32 |
33 | public class SonTest {
34 | public static void main(String[] args) {
35 | Son s = new Son();
36 | s.thinking();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/StaticDispatch.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | /**
8 | * 方法静态分派演示
9 | * @author zzm
10 | */
11 | public class StaticDispatch {
12 |
13 | static abstract class Human {
14 | }
15 |
16 | static class Man extends Human {
17 | }
18 |
19 | static class Woman extends Human {
20 | }
21 |
22 | public void sayHello(Human guy) {
23 | System.out.println("hello,guy!");
24 | }
25 |
26 | public void sayHello(Man guy) {
27 | System.out.println("hello,gentleman!");
28 | }
29 |
30 | public void sayHello(Woman guy) {
31 | System.out.println("hello,lady!");
32 | }
33 |
34 | public static void main(String[] args) {
35 | Human man = new Man();
36 | Human woman = new Woman();
37 | StaticDispatch sr = new StaticDispatch();
38 | sr.sayHello(man);
39 | sr.sayHello(woman);
40 | }
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/StaticResolution.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | /**
7 | * 方法静态解析演示
8 | *
9 | * @author zzm
10 | */
11 | public class StaticResolution {
12 |
13 | public static void sayHello() {
14 | System.out.println("hello world");
15 | }
16 |
17 | public static void main(String[] args) {
18 | StaticResolution.sayHello();
19 | }
20 |
21 | }
22 |
23 |
24 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/Test81.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test81 {
7 | public static void main(String[] args) {
8 | byte[] placeholder = new byte[64 * 1024 * 1024];
9 | System.gc();
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/Test82.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test82 {
7 | public static void main(String[] args){
8 | {
9 | byte[] placeholder = new byte[64 * 1024 * 1024];
10 | }
11 | System.gc();
12 | }
13 |
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/Test83.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test83 {
7 | public static void main(String[] args){
8 | {
9 | byte[] placeholder = new byte[64 * 1024 * 1024];
10 | }
11 | int a = 0;
12 | System.gc();
13 | }
14 |
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch8/Test84.java:
--------------------------------------------------------------------------------
1 | package ch8;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | public class Test84 {
7 | public static void main(String[] args) {
8 | int a;
9 | // System.out.println(a);
10 | }
11 |
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch9/98.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="ch9.JavaClassExecuter" %>
2 | <%@ page import="java.io.FileInputStream" %>
3 | <%@ page import="java.io.InputStream" %>
4 | <%
5 | InputStream is = new FileInputStream("c:/TestClass.class");
6 | byte[] b = new byte[is.available()];
7 | is.read(b);
8 | is.close();
9 |
10 | out.println("");
13 | %>
14 |
15 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch9/ByteUtils.java:
--------------------------------------------------------------------------------
1 | package ch9;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | /**
7 | * Bytes数组处理工具
8 | * @author
9 | */
10 | public class ByteUtils {
11 |
12 | public static int bytes2Int(byte[] b, int start, int len) {
13 | int sum = 0;
14 | int end = start + len;
15 | for (int i = start; i < end; i++) {
16 | int n = ((int) b[i]) & 0xff;
17 | n <<= (--len) * 8;
18 | sum = n + sum;
19 | }
20 | return sum;
21 | }
22 |
23 | public static byte[] int2Bytes(int value, int len) {
24 | byte[] b = new byte[len];
25 | for (int i = 0; i < len; i++) {
26 | b[len - i - 1] = (byte) ((value >> 8 * i) & 0xff);
27 | }
28 | return b;
29 | }
30 |
31 | public static String bytes2String(byte[] b, int start, int len) {
32 | return new String(b, start, len);
33 | }
34 |
35 | public static byte[] string2Bytes(String str) {
36 | return str.getBytes();
37 | }
38 |
39 | public static byte[] bytesReplace(byte[] originalBytes, int offset, int len, byte[] replaceBytes) {
40 | byte[] newBytes = new byte[originalBytes.length + (replaceBytes.length - len)];
41 | System.arraycopy(originalBytes, 0, newBytes, 0, offset);
42 | System.arraycopy(replaceBytes, 0, newBytes, offset, replaceBytes.length);
43 | System.arraycopy(originalBytes, offset + len, newBytes, offset + replaceBytes.length, originalBytes.length - offset - len);
44 | return newBytes;
45 | }
46 | }
47 |
48 |
49 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch9/DynamicProxyTest.java:
--------------------------------------------------------------------------------
1 | package ch9;
2 |
3 | import java.lang.reflect.InvocationHandler;
4 | import java.lang.reflect.Method;
5 | import java.lang.reflect.Proxy;
6 |
7 | /**
8 | * Created by lili on 2017/7/16.
9 | */
10 | public class DynamicProxyTest {
11 |
12 | interface IHello {
13 | void sayHello();
14 | }
15 |
16 | static class Hello implements IHello {
17 | @Override
18 | public void sayHello() {
19 | try {
20 | Thread.sleep(3000);
21 | } catch (InterruptedException e) {
22 | e.printStackTrace();
23 | }
24 | System.out.println("hello world");
25 | }
26 | }
27 |
28 | static class DynamicProxy implements InvocationHandler {
29 |
30 | Object originalObj;
31 |
32 | Object bind(Object originalObj) {
33 | this.originalObj = originalObj;
34 | return Proxy.newProxyInstance(originalObj.getClass().getClassLoader(), originalObj.getClass().getInterfaces(), this);
35 | }
36 |
37 | @Override
38 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
39 | long timeStart = System.currentTimeMillis();
40 | method.invoke(originalObj, args);
41 | System.out.println("方法执行耗费时间:"+(System.currentTimeMillis()-timeStart));
42 | return null;
43 | }
44 | }
45 |
46 | public static void main(String[] args) {
47 |
48 | System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles",true);
49 | IHello hello = (IHello) new DynamicProxy().bind(new Hello());
50 | hello.sayHello();
51 | }
52 | }
53 |
54 |
55 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch9/HackSystem.java:
--------------------------------------------------------------------------------
1 | package ch9;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | import java.io.ByteArrayOutputStream;
8 | import java.io.InputStream;
9 | import java.io.PrintStream;
10 |
11 | /**
12 | * 为JavaClass劫持java.lang.System提供支持
13 | * 除了out和err外,其余的都直接转发给System处理
14 | *
15 | * @author zzm
16 | */
17 | public class HackSystem {
18 |
19 | public final static InputStream in = System.in;
20 |
21 | private static ByteArrayOutputStream buffer = new ByteArrayOutputStream();
22 |
23 | public final static PrintStream out = new PrintStream(buffer);
24 |
25 | public final static PrintStream err = out;
26 |
27 | public static String getBufferString() {
28 | return buffer.toString();
29 | }
30 |
31 | public static void clearBuffer() {
32 | buffer.reset();
33 | }
34 |
35 | public static void setSecurityManager(final SecurityManager s) {
36 | System.setSecurityManager(s);
37 | }
38 |
39 | public static SecurityManager getSecurityManager() {
40 | return System.getSecurityManager();
41 | }
42 |
43 | public static long currentTimeMillis() {
44 | return System.currentTimeMillis();
45 | }
46 |
47 | public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
48 | System.arraycopy(src, srcPos, dest, destPos, length);
49 | }
50 |
51 | public static int identityHashCode(Object x) {
52 | return System.identityHashCode(x);
53 | }
54 |
55 | // 下面所有的方法都与java.lang.System的名称一样
56 | // 实现都是字节转调System的对应方法
57 | // 因版面原因,省略了其他方法
58 | }
59 |
60 |
61 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch9/HotSwapClassLoader.java:
--------------------------------------------------------------------------------
1 | package ch9;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 | /**
7 | * 为了多次载入执行类而加入的加载器
8 | * 把defineClass方法开放出来,只有外部显式调用的时候才会使用到loadByte方法
9 | * 由虚拟机调用时,仍然按照原有的双亲委派规则使用loadClass方法进行类加载
10 | *
11 | * @author zzm
12 | */
13 | public class HotSwapClassLoader extends ClassLoader {
14 |
15 | public HotSwapClassLoader() {
16 | super(HotSwapClassLoader.class.getClassLoader());
17 | }
18 |
19 | public Class loadByte(byte[] classByte) {
20 | return defineClass(null, classByte, 0, classByte.length);
21 | }
22 |
23 | }
24 |
25 |
26 |
--------------------------------------------------------------------------------
/understandingjvm/src/main/java/ch9/JavaClassExecuter.java:
--------------------------------------------------------------------------------
1 | package ch9;
2 |
3 | /**
4 | * Created by lili on 2017/7/16.
5 | */
6 |
7 | import java.lang.reflect.Method;
8 |
9 | /**
10 | * JavaClass执行工具
11 | *
12 | * @author zzm
13 | */
14 | public class JavaClassExecuter {
15 |
16 | /**
17 | * 执行外部传过来的代表一个Java类的Byte数组
18 | * 将输入类的byte数组中代表java.lang.System的CONSTANT_Utf8_info常量修改为劫持后的HackSystem类
19 | * 执行方法为该类的static main(String[] args)方法,输出结果为该类向System.out/err输出的信息
20 | *
21 | * @param classByte 代表一个Java类的Byte数组
22 | * @return 执行结果
23 | */
24 | public static String execute(byte[] classByte) {
25 | HackSystem.clearBuffer();
26 | ClassModifier cm = new ClassModifier(classByte);
27 | byte[] modiBytes = cm.modifyUTF8Constant("java/lang/System", "org/fenixsoft/classloading/execute/HackSystem");
28 | HotSwapClassLoader loader = new HotSwapClassLoader();
29 | Class clazz = loader.loadByte(modiBytes);
30 | try {
31 | Method method = clazz.getMethod("main", new Class[]{String[].class});
32 | method.invoke(null, new String[]{null});
33 | } catch (Throwable e) {
34 | e.printStackTrace(HackSystem.out);
35 | }
36 | return HackSystem.getBufferString();
37 | }
38 | }
39 |
40 |
41 |
--------------------------------------------------------------------------------
/up.push.git.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | git add -A && git commit -m "up" && git push
--------------------------------------------------------------------------------
/wikipedia/README.md:
--------------------------------------------------------------------------------
1 | https://www.artima.com/insidejvm/resources/index.html
2 |
3 | https://github.com/deephacks/awesome-jvm
4 |
5 | tools: https://www.eclipse.org/mat/
6 |
7 | Oracle官方工具类:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/index.html
8 |
9 | Site:
10 | http://www.javaperformancetuning.com/
11 | http://java-performance.info/
12 |
13 | Cache Coherence Protocols Analyzer
14 | https://kshitizdange.github.io/418CacheSim/final-report
15 |
16 | https://en.wikipedia.org/wiki/Cache_coherence
17 |
18 | GC:https://github.com/chewiebug/GCViewer
19 |
20 | ClassFile: https://github.com/ingokegel/jclasslib
21 |
22 | 1 对象内存分配在编译时还是运行时?
23 |
24 | 2 对象内存分配策略是什么?
25 |
26 | YGC问题排查过程:https://blog.csdn.net/ljw36060421/article/details/107308673?utm_medium=distribute.pc_feed.none-task-blog-personrec_tag-6.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-personrec_tag-6.nonecase&request_id=5f1fec4f9cc79f6252ce3616
27 |
28 | # Notes
29 |
30 | Core java doc:https://docs.oracle.com/en/java/javase/14/books.html
31 |
32 | https://openjdk.java.net/groups/hotspot/
33 |
34 | https://wiki.openjdk.java.net/display/HotSpot/Presentations
35 |
36 | https://en.wikipedia.org/wiki/HotSpot
37 |
38 | https://openjdk.java.net/projects/mlvm/ (userful slide)
39 |
40 | Jeremy Singer:http://www.dcs.gla.ac.uk/~jsinger/pdfs/
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/wikipedia/REVIEW.md:
--------------------------------------------------------------------------------
1 | # 复习
2 |
3 | - 聊聊JVM?
4 | - 静态角度:三大部分和内存模型,编译,执行引擎,内存管理,内存模型。
5 | - 动态角度:Javac**前端编译**Java文件成class文件,**执行引擎**中的类加载器将class加载到内存中,形成**内存区域**,执行程序指令,执行指令需要遵循**内存模型**,然后内存被**创建**和**回收**,执行后期,会有**后端编译**器将其编译成机器码。
6 | - 运行时数据结构是什么?
7 | - 虚拟机对象创建,内存布局,访问定位是什么?
8 | - OOM案例有哪些?
9 | - 内存分配策略是什么?
10 | - 内存回收策略是什么?
11 | - 如何判断对象需要回收?
12 | - 垃圾回收算法有哪些?
13 | - 垃圾回收器有哪些?
14 | - 类文件结构是什么样的?
15 | - 常见字节码指令有哪些?*invokevirtual* ,*invokevirtual*作用是什么?
16 | - 聊聊类加载?
17 | - 什么时候会触发类加载?
18 | - 类加载过程是什么?
19 | - 类加载模型是什么?
20 | - 有哪些类加载的案例?
21 | - 聊聊字节码执行引擎?
22 | - Java中方法调用实现原理是什么?
23 | - 运行时候的栈帧结构是什么?
24 | - 类加载案例有哪些?
25 | - 聊聊程序编译?
26 | - 前端编译和后端编译区别是什么?
27 | - JIT是什么?
28 | - 编译器优化技术有哪些?
29 | - 聊聊Java内存模型?
30 | - Java线程实现原理是什么?
31 | - 锁优化过程是什么样的?
32 |
--------------------------------------------------------------------------------