认识java
Posted 盖丽男
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了认识java相关的知识,希望对你有一定的参考价值。
目录
背景
最近在看《深入理解java虚拟机这本书》,看书的时候,有一些疑问,所以写篇博客总结一下。
java的发展轨迹和历史变迁图
疑问
都有哪些语言是跨平台的?
其实目前大部分语言都可以说是跨平台的,举几个例子
php通过不同操作系统平台的解释器来实现跨平台
go可以通过编译成不同操作系统平台的对应代码来实现跨平台
除了虚拟机,还有哪些跨平台方式
1.解释器
2.编译成对应操作系统代码
其他主流语言的内存管理是怎么做的?
- C/C++这种内存堆空间的申请和释放完全靠自己管理
- Java 依赖JVM来做内存管理,不了解jvm内存管理的机制,很可能会因一些错误的代码写法而导致内存泄漏或内存溢出
- Python内存管理是由私有堆空间管理的,所有的python对象和数据结构都存储在私有堆空间中。程序员没有访问堆的权限,只有解释器才能操作。
- Go的内存管理也是自动的,Go 的内存管理基本上参考 tcmalloc 来实现的,只是细节上根据自身的需要做了一些小的优化调整。
Java里都有哪些语法糖
- switch 支持 String 与枚举(java7)
- 泛型
- 自动装箱与拆箱
- 方法变长参数(java1.5)
- 枚举
- 内部类
- 数值字面量
- for-each
- try-with-resource
什么是Java模块化
模块化要解决的问题是:运行Java程序的时候,实际上我们用到的JDK模块,并没有那么多。不需要的模块,完全可以删除。
过去发布一个Java应用程序,要运行它,必须下载一个完整的JRE,再运行jar包。而完整的JRE块头很大,有100多M。怎么给JRE瘦身呢?
现在,JRE自身的标准库已经分拆成了模块,只需要带上程序用到的模块,其他的模块就可以被裁剪掉。
可以看一下廖雪峰的解释:
模块
Java的程序计数器和cpu的计数器有啥区别?
程序计数器(Program Counter Register),也有称作为PC寄存器。想必学过汇编语言的朋友对程序计数器这个概念并不陌生,在汇编语言中,程序计数器是指CPU中的寄存器,它保存的是程序当前执行的指令的地址(也可以说保存下一条指令的所在存储单元的地址),当CPU需要执行指令时,需要从程序计数器中得到当前需要执行的指令所在存储单元的地址,然后根据得到的地址获取到指令,在得到指令之后,程序计数器便自动加1或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令。
虽然JVM中的程序计数器并不像汇编语言中的程序计数器一样是物理概念上的CPU寄存器,但是JVM中的程序计数器的功能跟汇编语言中的程序计数器的功能在逻辑上是等同的,也就是说是用来指示 执行哪条指令的。
由于在JVM中,多线程是通过线程轮流切换来获得CPU执行时间的,因此,在任一具体时刻,一个CPU的内核只会执行一条线程中的指令,因此,为了能够使得每个线程都在线程切换后能够恢复在切换之前的程序执行位置,每个线程都需要有自己独立的程序计数器,并且不能互相**扰,否则就会影响到程序的正常执行次序。因此,可以这么说,程序计数器是每个线程所私有的。
在JVM规范中规定,如果线程执行的是非native方法,则程序计数器中保存的是当前需要执行的指令的地址;如果线程执行的是native方法,则程序计数器中的值是undefined。
由于程序计数器中存储的数据所占空间的大小不会随程序的执行而发生改变,因此,对于程序计数器是不会发生内存溢出现象(OutOfMemory)的。
栈帧是啥
这个问题涉及到的内容比较多,
栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构。它是虚拟机运行时数据区中的虚拟机栈的栈元素。
栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。
每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机里面从入栈到出栈的过程。
可以看一下这篇博客的讲解:Java —— 运行时栈帧结构
程序运行的某个时刻,Java中没有被调用代码,是否被加载了?如果加载了,在哪儿存放?
程序代码都会被存放在方法区
为什么反射,动态代理会导致方法区压力过大?
标记复制和标记整理的区别是啥
像Serial,ParNew,Parallel Scaveng这类年轻代的垃圾回收器,都是使用的标记复制,Serial Old、Parallel Old老年代的垃圾回收器却是使用的标记整理,CMS算是标记清除和标记整理的混合使用。
这个写的很好,可以参考: 并发垃圾收集器(CMS)为什么没有采用标记-整理算法来实现?
以上是关于认识java的主要内容,如果未能解决你的问题,请参考以下文章