第一部分 走进java
1.1 概述
我们直接来了解一下Java的优点
它摆脱了硬件平台的束缚,实现了“一次编写,到处运行”的理想;它提供了一个相对安全的内存管理和访问机制,避免了绝大部分的内存泄露和指针越界问题;它实现了热点代码检测和运行时编译及优化,这使得Java应用能随着运行时间的增加而获得更高的性能;它有一套完善的应用程序接口,还有无数来自商业机构和开源社区的第三方类库来帮助它实现各种各样的功能……
1.2 Java技术体系
- Java程序设计语言
- 各种硬件平台上的虚拟机
- class文件格式
- Java api类库
- 来自商业机构和开源机构的第三方库
java技术体系所包含的内容
以上是根据各个组成部分的功能来进行划分的,如果按照技术所服务的领域来划分,或者说按照Java技术关注的重点业务领域来划分,Java技术体系可以分为4个平台,分别为:
-
Java Card:支持一些Java小程序(Applets)运行在小内存设备(如智能卡)上的平台。
-
Java Card:支持一些Java小程序(Applets)运行在小内存设备(如智能卡)上的平台。
-
Java SE(Standard Edition):支持面向桌面级应用(如Windows下的应用程序)的Java平台,提供了完整的Java核心API,这个版本以前称为J2SE。
-
Java SE(Standard Edition):支持面向桌面级应用(如Windows下的应用程序)的Java平台,提供了完整的Java核心API,这个版本以前称为J2SE。
由于此部分太过枯燥,所有up直接跳过,后续会emmm 更新??
第二部分 自动内存管理机制
java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来。(目前还不了解这句话)
2.1 概述
c++ 和 c 的开发人员在,内存管理领域,他们既是皇帝,又时基层的劳动人民 ---即拥有每一个对象的'所有权' ,又担负着每一个对象生命开始到终结的维护责任。
但对于,java程序员来说,在虚拟机自动内存管理机制的帮助下,不在为每一个new操作去写配对的delete/free代码,不容易出现内存泄漏和内存溢出的问题
内存泄漏和内存溢出的问题
我们简单了解一下, 用通俗的话来讲
- 内存溢出:你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,出现溢出。
- 内存泄漏:你用new申请了一块内存,后来很长时间都不再使用了(按理应该释放),但是因为一直被某个或某些实例所持有导致 GC 不能回收,也就是该被释放的对象没有释放。
怎样避免内存泄漏呢
1、尽早释放无用对象的引用
2、使用字符串处理时避免使用String,应使用StringBuffer,每一个String对象都得独立占用内存一块区域
3、尽量少用静态变量,因为静态变量存放在永久代(方法区),永久代基本不参与垃圾回收
4、避免在循环中创建对象
2.2 运行时的数据区域
java虚拟机运行时数据区
2.2.1 程序计数器(pc)
pc 是控制器中的一部分,它可以看成是当前线程所执行的字节马的行号指示器,简单点说,他就是只是你该执行那条指令了。
由于java虚拟机的多线程是通过线程轮流切换并分配处理及执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一个线程中的指令。因此为了线程切换后能恢复到正确的执行位置,每条线程都需要又自己的一个独立的程序计数去,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为‘线程私有’的内存。
如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
2.2.2 java虚拟机栈
概念
Java虚拟机栈(Java Virtual Machine Stacks)是线程私有的,栈使用的内存不需要保证是连续的,栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用至执行完成的过程,都对应着一个栈帧在虚拟机栈里从入栈到出栈的过程。
Java虚拟机以方法作为最基本的执行单元,“栈帧”(Stack Frame)则是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)的栈元素。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。
在运行时的线程中,只有当前栈帧有效(Java虚拟机栈中栈顶的栈帧),与当前栈帧相关联的方法称为当前方法。每调用一个新的方法,被调用方法对应的栈帧就会被放到栈顶(入栈),也就是成为新的当前栈帧。当一个方法执行完成退出的时候,此方法对应的栈帧也相应销毁(出栈)。
2.2.3 本地方法栈
本地方法栈的功能和特点类似于虚拟机栈,均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常。本地方法栈服务的对象是JVM执行的native方法,其就是一个java调用非java代码的接口,作用是与操作系统和外部环境交互。
如果某个虚拟机实现的本地方法接口是使用C连接模型的话,那么它的本地方法栈就是C栈。当C程序调用一个C函数时,其栈操作都是确定的。传递给该函数的参数以某个确定的顺序压入栈,它的返回值也以确定的方式传回调用者。同样,这就是虚拟机实现中本地方法栈的行为。
这里我们来简单了解一下native是干啥的
native 是用做java 和其他语言(如c++)进行协作时使用的,也就是native 后的函数的实现不是用java写的。
既然都不是java,那就别管它的源代码了,我们只需要知道这个方法已经被实现即可。
native的意思就是通知操作系统, 这个函数你必须给我实现,因为我要使用。 所以native关键字的函数都是操作系统实现的, java只能调用。
java是跨平台的语言,既然是跨了平台,所付出的代价就是牺牲一些对底层的控制,而java要实现对底层的控制,就需要一些其他语言的帮助,这个就是native的作用了。
up会努力完善本章内容,并优化以上内容使用更加直白的语言介绍,以上内容会优化的
参考书籍 深入理解java虚拟机