20191124
java与c++
windows下的java与c++
程序如何通过JRE的java(%SystemRoot%\system32下的java)执行java程序的,最终主要是将java的程序通过server下的jvm.dll
(c++实现的)的window下的MFC微软基础类库最终将代码运行在windowns环境下的,这是java程序能够再windowns下运行的条件。因为java的基础类库jt.jar在jvm初始化的时候会加载,这部分jar包中包含了IO、网络之类的好多基础类库,其中很多的方法是native方法,但是由于windows的特殊性,微软提供了这么一套windowns接口来配合java能够再windows上运行。
linux下的java与c++
java字节码的执行,首先编译字节码class,再class文件中就包含了许多的jvm指令,最终由jvm指令执行具体的代码,比如局部变量的赋值和方法的调用,java的jdk中由于jt.jar包中实现了基础了IO和网络的功能(大部分功能是c++实现的),因此许多的操作都会依赖c++的native方法,这些方法在jvm中会被调用执行
比如:
net包中的ipv4这个就会调用native方法。所以bootstrap类加载器才会首先吧这个加载进来。具体加载那些看下面的java类加载
JVM
https://blog.csdn.net/guo20082200/article/details/80181907
JVM是用来执行class字节码的,这样回答肯定不行
JVM有自己的一套,他是根据自己设计java程序的运行方式来搞的一套独立运行字节码的框架
首先JVM有自己的内存划分方式 堆区、栈区、perm区(meta区)……
然后JVM有自己的指令集,会将java源文件编译好的class中的指令对应操作到不同的内存中,因此我们再启动一个java程序的时候也别称为启动了一个JVM实例,也就存在了我们再启动一个java ……类的时候会有一大堆的jvm参数 Xms=2048m……,所有的这些都是为了初始化这个框架,然后再按照我们的要求启动好了之后再运行我们的java的main方法,这样才产生了各种各样的java应用(web、中间件、大数据服务)。
可以把他理解为再OS上又创建了一层程序的调度器,这个调度器具体调度java程序的执行流程。
JVM的内存模型
这篇讲JVM讲的不错,后期总结一下 https://www.jianshu.com/p/0ecf020614cb
Tenured这个英文的意思是老年代的意思
JDK 与JRE的区别
JDK
JDK是用来产生java程序,即最终放在JRE上运行产品的工具包
jdk是java开发者用来开发java程序的工具包,那么它和jre的最大区别在于它比JRE多出一些东西来是专门用来做开发用的,通过观察可以发现在JDK的bin目录下会有很多的工具,但是其中有几个在JRE下面是没有的:
区别1:工具的区别
比如javac、jstack、jar、jvisualvm(做内存dump分析),概况一句话就是在JDK当中存在一些与编译、调试相关的工具在JRE下的没有的,试想一下作为一个开发人员,光开发和编译代码是远远不够的,因此JDK作为开发者的工具提供了满足开发者一应俱全的工具,所以这些工具全部被封装到了JDK当中,这些是JRE中没有的。
区别2:JRE的区别(JDK的工具>JRE的工具)
这里大家经常会发现一个问题就是,为什么在JDK下面也有一个JRE目录,而且很奇怪的是这个JDK下面的JRE目录的大小竟然比纯JRE的还要大,而且我们不是说JRE是java运行的环境,为什么JDK下面还要有一个JRE呢,这不是多此一举么。
那是因为,上面描述了JDK是用来开发的,JDK下面的开发工具javac、jstack、jvisualvm这些工具都是java程序,那么这些程序可不是普通的java程序,它们是开发java程序的程序,可以理解为java程序的工厂,所以这些程序在执行的时候需要专门配套一个新的JRE来执行这些个工具javac、jstack、jvisualvm,所以我们的SUN公司也偷懒将JRE拷贝过来,同事又加了一些专门用来支持开发的接口。
JRE
JRE用来执行JDK产生的运行产品的环境
通过上面对JDK 的描述,JRE是个啥东东应该清楚了,不过这里有一个神奇的东西是再windowns中会出现的一个现象,那就是我们再path中没有设置jre/bin到path中,为什么能够成功执行程序呢,我们最初使用的java命令到底执行的是jdk下面的还是jre下面的呢?而且又一次遇到过一个问题是通过替换了%SystemRoot%\system32%下面的java.exe才好的
答案:
大家肯定在安装jdk的时候完毕会提示要不要安装jre,我们一般都装了,我们以为安装了jre就没事了,其实不然,这个安装包执行安装完毕后干了一件事情:
将jre下面的java.exe拷贝到了%SystemRoot%\system32%,这个路径是早已经再PATH中的,所以我们执行java命令的时候其实执行的是这个,这也就回答了上次哪个替换这个java.exe文件的问题了。
关于JRE这里其实也没啥可说的了,通过JDK的描述已经知道JRE就是运行普通java程序的,它有自己的jvm.dll(windowns下的虚拟机),真正用来跑java代码的,不包括编译、调试的工具,换言之JRE只负责跑不负责生产和调试。
https://blog.csdn.net/shaochenshuo/article/details/78507132
Java 的类加载
java的类加载器有那些,都是用来干啥的
通过代码可以知道java程序的第三级别的类加载器为
Launcher$AppClassLoader
{code}
public class TestDemo {
public static void main(String[] args) {
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (URL url : urls) {
System.out.println(url.toExternalForm());
}
System.out.println("==========================");
//扩展类加载器Main
ClassLoader classLoader = TestDemo.class.getClassLoader();
System.out.println(classLoader.getClass());
System.out.println("father is"+classLoader.getParent());
//表示当前线程的类加载器——应用程序类加载器
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
System.out.println("表示当前线程的类加载器——应用程序类加载器"+contextClassLoader);
//—启动类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println("—启动类加载器"+systemClassLoader);
System.out.println(classLoader==contextClassLoader);
System.out.println(systemClassLoader==contextClassLoader);
System.out.println(String.class.getClassLoader());
}
{code}
执行结果中
这个是bootstrap类加载器加载的jar包,看到没,上面举例子说的哪个rt.jar被加载进来了。
即JVM再执行的时候,首当其冲的是sun.misc.Launcher$AppClassLoader,这个类,于是当这个类加载不到需要的class的时候,就需要parent加载器issun.misc.Launcher$ExtClassLoader来搞了,如果parent还找不到,那就只能找bootstrap来搞定了
三种加载器的分工
https://blog.csdn.net/m0_38075425/article/details/81627349
https://blog.csdn.net/zhaocuit/article/details/93038538 这个很直观
类加载器的JVM源码
http://ifeve.com/jvm-classloader/