今天看到一个牛人的贴子,上面提了一些关于JVM的问题,但是没有答案,所以在这里求解答.贴子如下:
JVM是Java程序的运行环境,因此对于JVM的掌握有助于理解Java程序的执行以及编写,尤其是运行时碰到的一些诡异问题,那么怎么样能考察自己对于JVM关键知识点的掌握情况,帮助学习JVM机制呢,在这篇blog中来探讨下。对于Java程序而言,JVM的关键机制有:字节码的加载、方法的执行、对象内存的分配和回收、线程和锁机制,这几个机制涉及到的jvm的知识点远没有写这几个字这么简单,里面的复杂度还是非常高的。字节码的加载
JVM通过ClassLoader来完成字节码的动态加载,这里面涉及到的主要是ClassLoader的双亲委派、ClassLoader的编写方法、Class是否被加载的唯一标识以及Class的加载过程。
在考察的时候我觉得可以以这么两道简单的题来考察:
1、写一段将目录中指定的.class文件加载到JVM的程序,并通过Class对象获取到完整类名等信息;
2、一段展示代码,里面包含一个全局静态整型变量,问如果用两个ClassLoader加载此对象,执行这个整型变量++操作后结果会是怎么样的?
方法的执行
JVM有自己的一套指令系统,字节码中即已经是指令了,需要大概掌握了JVM对static、interface、instance、构造器采用的不同的执行方法,另外就是JVM中反射的实现(可以以Sun JDK来举例)、动态代理的实现,最后相关的就是JVM执行字节码的方式(解释、JIT、Hotspot),以及什么时候触发编译成机器码,如何控制。
在考察的时候我觉得可以以这么三道题来考察:
1、A a=new A();a.execute();和IA a=new A();a.execute();执行有什么不同;
2、反射的性能低的原因是?
3、编写一段程序,动态的创建一个接口的实现,并加载到JVM中执行;(可以允许用BCEL等工具)对象内存的分配和回收
这块涉及的知识点也是比较的多,例如JVM内存区域的划分、自然类型和引用类型的内存分配的不同、TLAB、GC的算法、Sun JDK对于GC的实现、GC触发的时机、GC的跟踪和分析的方法。
在考察的时候我觉得可以以这么三道题来考察:
1、经典的String比较程序题:
String a="a";
String b="b";
String ab="ab";
(a+b)==ab; ?? (引深题,如何才能让(a+b)==ab)
("a"+"b")==ab; ??
2、写一段程序,让其OutOfMemory,或频繁执行Minor GC,但又不触发Full GC,又或频繁执行Full GC,但不执行minor GC,而且不OutOfMemory,甚至可以是控制几次Minor GC后发生一次Full GC;
3、详细讲解GC的实现,例如minor GC的时候导致是[code=Java]怎么回收对象内存的,Full GC的时候是怎么回收对象内存的。[/code]
线程和锁机制
这块涉及的知识点仍然是非常的多,例如线程中变量的操作机制、线程调度机制、线程的状态以及控制方法、线程的跟踪和分析方法、同步关键字、lock/unlock的原理等。
在考察的时候我觉得可以以这么几道题考察下:
1、i++的执行过程;
2、一个线程需要等待另外一个线程将某变量置为true才继续执行,如何编写这段程序,或者如何控制多个线程共同启动等;
3、控制线程状态的转换的方法,或者给几个thread dump,分析下哪个线程有问题,问题出在哪;
4、static属性加锁、全局变量属性加锁、方法加锁的不同点?
JVM是Java程序的运行环境,因此对于JVM的掌握有助于理解Java程序的执行以及编写,尤其是运行时碰到的一些诡异问题,那么怎么样能考察自己对于JVM关键知识点的掌握情况,帮助学习JVM机制呢,在这篇blog中来探讨下。对于Java程序而言,JVM的关键机制有:字节码的加载、方法的执行、对象内存的分配和回收、线程和锁机制,这几个机制涉及到的jvm的知识点远没有写这几个字这么简单,里面的复杂度还是非常高的。字节码的加载
JVM通过ClassLoader来完成字节码的动态加载,这里面涉及到的主要是ClassLoader的双亲委派、ClassLoader的编写方法、Class是否被加载的唯一标识以及Class的加载过程。
在考察的时候我觉得可以以这么两道简单的题来考察:
1、写一段将目录中指定的.class文件加载到JVM的程序,并通过Class对象获取到完整类名等信息;
2、一段展示代码,里面包含一个全局静态整型变量,问如果用两个ClassLoader加载此对象,执行这个整型变量++操作后结果会是怎么样的?
方法的执行
JVM有自己的一套指令系统,字节码中即已经是指令了,需要大概掌握了JVM对static、interface、instance、构造器采用的不同的执行方法,另外就是JVM中反射的实现(可以以Sun JDK来举例)、动态代理的实现,最后相关的就是JVM执行字节码的方式(解释、JIT、Hotspot),以及什么时候触发编译成机器码,如何控制。
在考察的时候我觉得可以以这么三道题来考察:
1、A a=new A();a.execute();和IA a=new A();a.execute();执行有什么不同;
2、反射的性能低的原因是?
3、编写一段程序,动态的创建一个接口的实现,并加载到JVM中执行;(可以允许用BCEL等工具)对象内存的分配和回收
这块涉及的知识点也是比较的多,例如JVM内存区域的划分、自然类型和引用类型的内存分配的不同、TLAB、GC的算法、Sun JDK对于GC的实现、GC触发的时机、GC的跟踪和分析的方法。
在考察的时候我觉得可以以这么三道题来考察:
1、经典的String比较程序题:
String a="a";
String b="b";
String ab="ab";
(a+b)==ab; ?? (引深题,如何才能让(a+b)==ab)
("a"+"b")==ab; ??
2、写一段程序,让其OutOfMemory,或频繁执行Minor GC,但又不触发Full GC,又或频繁执行Full GC,但不执行minor GC,而且不OutOfMemory,甚至可以是控制几次Minor GC后发生一次Full GC;
3、详细讲解GC的实现,例如minor GC的时候导致是[code=Java]怎么回收对象内存的,Full GC的时候是怎么回收对象内存的。[/code]
线程和锁机制
这块涉及的知识点仍然是非常的多,例如线程中变量的操作机制、线程调度机制、线程的状态以及控制方法、线程的跟踪和分析方法、同步关键字、lock/unlock的原理等。
在考察的时候我觉得可以以这么几道题考察下:
1、i++的执行过程;
2、一个线程需要等待另外一个线程将某变量置为true才继续执行,如何编写这段程序,或者如何控制多个线程共同启动等;
3、控制线程状态的转换的方法,或者给几个thread dump,分析下哪个线程有问题,问题出在哪;
4、static属性加锁、全局变量属性加锁、方法加锁的不同点?
不深入学习jvm的原理,估计答不上来
你应该会把,不是研究jvm好长时间了吗
基本上 java.sun.com 很粗略地把 Java 分为三个部分 (1) J2SE ( Java 2 Standard Edition )
(2) J2EE ( Java 2 Enterprise Edition )
(3) J2ME ( Java 2 Micro Edition ) 新手, 大概都要由 J2SE 开始学习,
比较需要了解的就是 SCJP 考题的范围
刚开始你大可不必花时间去研究 AWT 或 Swing 的基本概念
但是我认为你们要对基本语法及数据结构要清楚
接着, 必须学会如何查询 API ( javadoc ) 其实, Java 并不难学, 比 VB 难一些些,
但是可以处理的范围却比 VB 大很多,
只要能够设定好 jdk 与 classpath,
开发就没有太大问题,
刚开始我会建议你们直接使用 UltraEdit 或 EditPlus 这些文书处理工具
练习来建立简单的 variable, loop 等等...
接着学习一些 free 的 IDE , eclipse, netbeans and etc.. ( 请参阅 IDE 版 ) 很多人会拿 C 和 Java 相比较
基本上, Java 处理硬件的能力大多要透过 JNI 与 Driver 沟通
架构在 JVM 上面执行效能也很难与 C 抗衡
但是, 简单容易上手 是他的优势
OO 程序设计也随着 java 的发展突飞猛进,
相对的, 在学的学生, 尤其是信息相关科系的,
可以顺便了解 UML 及软件工程,
这个站有许多高手会替你解答疑问的 所谓的 Java 高手其实没有什么 ( sorry, 诸位高手.... )
可能是读了比较多的技术文件或知道比较多的资源可以利用
一个语言能够让工程师轻易地建构出一套系统
就是很好的语言, 所以你们可以很快乐地开始学习
更重要的事情, 使用 java 开发的人们
非常热心开放他们的原始码,
你们可以使用他们的 binary jar, 或参考他们的 source code
堆栈出你们想要建立的系统 ( plz check their license ) 等到你能够写出九九表, 控制住一些 collection,
能够读得懂 Java API 的 javadoc ,
你大概就可以做一些选择
想要做 application , 就可以钻研于 awt , swing 等等
想要做 webapps, 就可以钻研 jsp/servlet 等等
想要做 pda/ phone, 就可以钻研 midp, j2me 等等
第一个问题:
1、写一段将目录中指定的.class文件加载到JVM的程序,并通过Class对象获取到完整类名等信息;
答案(不完整,只写了加载一个文件,再加上遍历目录就行了):package com.tangqiao;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;public class MyClassLoader extends ClassLoader {
public static final String drive = "d:/";
public static final String fileType = ".class"; public Class findClass(String name) {
byte[] data = loadClassData(name);
return defineClass(name, data, 0, data.length);
} public byte[] loadClassData(String name) {
name = name.substring(name.lastIndexOf('.'));
FileInputStream fis = null;
byte[] data = null;
try {
fis = new FileInputStream(new File(drive + name + fileType));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int ch = 0;
while ((ch = fis.read()) != -1) {
baos.write(ch);
}
data = baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return data;
} public static void main(String[] args) throws Exception {
MyClassLoader loader = new MyClassLoader();
Class objClass = loader.loadClass("com.tangqiao.Test1", true);
Object obj = objClass.newInstance();
System.out.println(objClass.getName());
System.out.println(objClass.getClassLoader());
}}
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;public class MyClassLoader extends ClassLoader {
public static final String drive = "d:\\com\\";
public static final String fileType = ".class"; public Class findClass(String name) {
byte[] data = loadClassData(name);
return defineClass(name, data, 0, data.length);
} public byte[] loadClassData(String name) {
name = name.substring(name.lastIndexOf('.')+1);
FileInputStream fis = null;
byte[] data = null;
try {
fis = new FileInputStream(new File(drive + name + fileType));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int ch = 0;
while ((ch = fis.read()) != -1) {
baos.write(ch);
}
data = baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return data;
} public static void main(String[] args) throws Exception {
MyClassLoader loader = new MyClassLoader();
MyClassLoader loader2 = new MyClassLoader();
Class obj = loader.loadClass("Test2", true);
Class obj2 =loader2.loadClass("Test2", true);
System.out.println(obj.getName());
System.out.println(obj.getClassLoader());
System.out.println(obj2.getName());
System.out.println(obj2.getClassLoader());
Field f1 = obj.getField("v");
f1.setInt("v", 2);
Field f2 = obj2.getField("v");
f2.setInt("v", 3);
System.out.println(f1.getInt("v"));
System.out.println(f2.getInt("v"));
/*
Test1 ins1 = (Test1)obj.newInstance();
Test1 ins2 = (Test1)obj.newInstance();
ins1.v ++;
System.out.println(ins1.v);
System.out.println(ins2.v);*/
//System.out.println(objClass.getName());
//System.out.println(objClass.getClassLoader());
}}测试结果如下(两种测试方法):
Test2
com.tangqiao.MyClassLoader@a90653
Test2
com.tangqiao.MyClassLoader@1fb8ee3
3
3
Test2
sun.misc.Launcher$AppClassLoader@1a46e30
Test2
sun.misc.Launcher$AppClassLoader@1a46e30
3
3
String a="a";
String b="b";
String ab="ab";
(a+b)==ab; ?? (引深题,如何才能让(a+b)==ab)
("a"+"b")==ab; ??
答案:
public class Test1 {
public static void main(String[] args) {
//1、经典的String比较程序题:
String a="a";
String b="b";
String ab="ab";
// (a+b)==ab; ?? (引深题,如何才能让(a+b)==ab)
// 答:输出false, 因为 a+b生成一个临时变量,其地址和ab的地址不同
System.out.println((a+b)==ab);
// ("a"+"b")==ab; ??
// 答:输出true, 因为 "a"+"b"不是变量运算,所以没有生成临时变量,值就是"ab"的地址
System.out.println(("a"+"b")==ab);
// 引深题, 加上final即可,输出true,因为不是变量运算,所以没有生成临时变量
// 编译期应该就运算完成了
final String a1 = "a";
final String b1 = "b";
System.out.println((a1+b1)==ab);
}
}
JVM的关于回收的那些东西,还是找找书看看,了解一下每种GC触发的条件,就很清楚了