转载请注明原创出处,谢谢!

最近没有什么实战,准备把JVM知识梳理一遍,先以开发人员的交流来谈谈jvm这块的知识以及重要性,依稀记得2、3年前用solr的时候老是经常oom,提到oom大家应该都不陌生,那个时候也并没有从根本解决oom,由于对jvm不熟悉,只是去百度,到处都是配置jvm参数的,那个时候啥不懂,直接粘贴,但是并没有解决问题,通过这个就告诉我们作为开发人员也需要对jvm很熟悉才行,问题来了,很多人会说我的代码并没有出现oom啊,不需要关注啊,因为不理解不知道重要性,可以回头看看的我的JVM菜鸟进阶高手之路一到九篇系列,可能很多人说还没有到那么高级,不需要理解,我也告诉你也是不对的,且听我慢慢道来。

谈到jvm首先需要谈的是,JAVA虚拟机规范,这个就类似jdbc规范一样,定义了一些规范,oracle有oracle的实现,mysql有mysql的实现,JAVA虚拟机规范也一样,java虚拟机有很多,IBM、Apache Harmony等,每个都有些细节不一样,但是大体符合JAVA虚拟机规范的,由于Oracle收购SUN之后,Oralce主要有JRockit和Hotspot虚拟机了,后来将其进行整合了,不然维护两套麻烦,就和原来的struts1和struts2一样,Oralce主要是以Hotspot来的,把JRockit里面的一些优点也慢慢加入到其中。目前市面上Hotspot占用率是最高的,一般说到JAVA虚拟机基本都是Hotspot虚拟机。JAVA8虚拟机规范地址:http://docs.oracle.com/javase/specs/jvms/se8/html/index.html,按照道理应该去阅读阅读的,虽然java语言与java虚拟机有密切的关系,但是两者是完全不同的内容,像Scala、Clojure、Groovy等语言都是跑在JAVA虚拟机上面的,可以产生各种各样的跨平台语言,除了语言特性不一样,他们可以共享JAVA虚拟机带来的跨平台性、垃圾回收器、以及即使编译(看到这里都应该明白这些的JAVA虚拟机拥有的不是java语言规范定义的,java语言规范地址:http://docs.oracle.com/javase/specs/jls/se8/html/index.html),稍微解释下为什么用JAVA虚拟机就可以做到跨平台呢?依稀记得当时刚刚学习java的时候有句口号“一次编译,到处运行。”Java程序理想上,并不理会真正执行哪个平台,只要知道如何执行于JVM就可以了,至于JVM实际上如何与底层平台沟通,那是JVM自己的事。由于JVM实际上相当于Java程序的操作系统,JVM就负责了Java程序的各种资源管理。

我们要记住两点:

  • JVM就是Java程序的操作系统,JVM的可执行文件就是.class文件。
  • Java虚拟机屏蔽了操作系统之间的差异,但是不同的系统使用的虚拟机不同。

与其他语言相比,Java程序能够做到“编译一次,到处运行”,可见它的跨平台性非常强。其实JVM就是在操作系统层面有抽象了一层虚拟机,这样的好处可以屏蔽底层细节,有每个具体的平台的虚拟机实现即可,但是对外提供的是一致的(比如windows需要安装windows版的jdk,linux需要安装linux版的jdk就是这个原因,jvm虚拟机帮我们屏蔽到了底层的细节)。

一直有一个疑惑,Oracle的jdk和OpenJDK到底有什么关系呢?

Oracle/Sun JDK与OpenJDK的区别和联系如下: - OpenJDK原是SunMicrosystems公司为Java平台构建的Java开发环境(JDK)的开源版本,完全自由,开放源码。Sun Microsystems公司在2006年的JavaOne大会上称将对Java开放源代码,于2009年4月15日正式发布OpenJDK。甲骨文在 2010 年收购SunMicrosystem之后接管了这个项目。

  • oracle/Sun JDK里面包含的JVM是HotSpotVM,HotSpot VM只有非常非常少量的功能没有在OpenJDK里,那部分在Oracle内部的代码库里。这些私有部分都不涉及JVM的核心功能。所以说,Oracle/Sun JDK与OpenJDK其实使用的是同一个代码库。
  • 从一个Oracle内部员工的角度来看,当他要构建OracleJDK时,他同样需要先从http://hg.openjdk.java.NET签出OpenJDK,然后从Oracle内部的代码库签出私有的部分,放在OpenJDK代码下的一个特定目录里,然后构建。值得注意的是,Oracle JDK只发布二进制安装包,而OpenJDK只发布源码。

知道关系之后,其实很多就释然了,其实阿里的jdk就是基于OpenJDK定制的,所以看看OpenJDK对理解JVM很有帮助的,OpenJDK的github地址如下:https://github.com/dmlloyd/openjdk,既然都看见了OpenJDK的源码,那么是否有兴趣编译编译。

用final可以提高性能,为什么呢?

依稀记得以前老师说,用final可以提高性能,为什么呢?由于类的加载机制,关于一个*.class如何加载进来,如何一系列的操作后续会进行介绍,由于类的加载机制会提到一些热替换,热加载,以及阅读tomcat源码的时候可以了解到他是怎么处理加载的,由于final常量在准备阶段就初始化了,而并不是在初始化结点处理的,所以可以提高程序相应效率。
申明为final的情况:

  • 不需要重新赋值的变量,包括类属性、局部变量。
  • 对象参数前面加final,表示不允许修改引用的指向。
  • 类的方法不可以被重写。

由于final关键字,在并发锁的时候,不可变的一些情况锁是无效的

比如锁一个Integer、Double、String等是不行的,你说这些你对JVM不了解能行吗?

JAVA虚拟机对各各数据类型的表示,所以引入了关于,原码,补码,反码等概念,为什么需要补码呢?

补码的好处:

  • 使用补码可以没有任何歧义的表示0。
  • 补码可以很好的参与二进制的运算,补码相加符号位参与运算, 这样就简单很多了。那就可以明白为什么数据溢出的概念了,经常看到

    byte a=(byte)(127+1);
    System.out.println(a);

如果不了解JVM怎么能懂,还有两个值相同的Integer型值进行==比较时:

Integer a=125;
 Integer b=125;
 Integer d=300;
 Integer c=300;
System.out.println(c==d);
System.out.println(a==b);

运行结果为falsetrue?为什么呢? 查看源码: 这儿的IntegerCache有一个静态的Integer数组,在类加载时就将-128 到 127 的Integer对象创建了,并保存在cache数组中, 一旦程序调用valueOf 方法,如果i的值是在-128 到 127 之间就直接在cache缓存数组中去取Integer对象,超出 -128 ~ +127 范围的数字就要即时构建新的Integer对象,可以通过JVM参数 -XX:AutoBoxCacheMax来进行调整。 那么== 和equals的区别,== 是进行地址及值比较,无法对==操作符进行重载,而对于equals方法,Integer里面的equals方法 重写了Object的equals方法,所以,相同类型的包装类对象直接的值比较全部使用equals方法比较,并且能用基本数据类型 就应该用基本数据类型,这些你不了解JVM你那里知道呢?

根据IEEE754定义的浮点数的格式,所以涉及到钱的小数类型必须使用BigDecimal,禁止使用float和double,为什么呢?

不懂JVM可以?后续会讲。

慎用Object的clone方法拷贝对象,深拷贝,浅拷贝。

你不了解jvm模型咋知道呢?还有Object的finalize你不了解JVM怎么理解呢?

对于String的一些操作,String的文章最多。+运算符号

String str = "start";
 for(int i=0; i<100; i++){
     str = str + "hello";
}

反编译出的字节码文件显示每次循环都会new出一个StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象,造成内存资源浪费。

其他

HashMap、ArrayList、StringBuilder等的扩容机制,会浪费空间以及性能(可能存在跨代引用的问题),特别在并发情况下面可能会死锁,后续分享hashMap的cpu 100%情况,所以集合初始化时,尽量指定集合初始值大小,你不了解jvm怎么可以呢?还有很多框架,netty等对外内存(堆外空间),多线程相关ThreadLocal等,还有锁在java虚拟机中的实现优化,你不了解怎么可以呢?
今天仅仅是开场白,后续会有系列基础知识文章出来。大家一起进步。


个人公众号

JVM菜鸟进阶高手之路十(基础知识开场白)的更多相关文章

  1. JVM菜鸟进阶高手之路十四:分析篇

    转载请注明原创出处,谢谢! 题目回顾 JVM菜鸟进阶高手之路十三,问题现象就是相同的代码,jvm参数不一样,表现的现象不一样. private static final int _1MB = 1024 ...

  2. JVM菜鸟进阶高手之路十二(jdk9、JVM方面变化, 蹭热度)

    转载请注明原创出处,谢谢! 经过 4 次跳票,历经曲折的 Java 9 正式版终于发布了!今天看着到处都是jdk9发布了,新特性说明,心想这么好的蹭热度计划能错过嘛,哈哈,所以就发了这篇文章. 目前j ...

  3. JVM菜鸟进阶高手之路十三(等你来战!!!)

    转载请注明原创出处,谢谢! 前几天有个朋友问了我个问题,下面给大家分享下,希望大家积极在评论区进行评论留言,等你来战!!! 先来个趣味题,热身下,引出后面的jvm题目. 地上的影子是那个人的? 地上的 ...

  4. JVM菜鸟进阶高手之路一[z]

    https://mp.weixin.qq.com/s/qD1LFmsOiqZHD8iZX97OfA? 问题现象 代码如下,使用 ParNew + Serial Old 回收器组合与使用 ParNew ...

  5. JVM菜鸟进阶高手之路二(JVM的重要性,Xmn是跟请求量有关。)

    转载请注明原创出处,谢谢! 今天看群聊jvm,通常会问ygc合适吗? 阿飞总结,可能需要2个维度,1.单位时间执行次数,2.执行时间 ps -p pid -o etime 查看下进程的运行时间, 17 ...

  6. JVM菜鸟进阶高手之路一(一次与笨神,阿飞近距离接触修改JVM)

    转载请注明原创出处,谢谢! 今天在JVMPocket群里面看见,阿牛发了一个gc截图,之后ak47截图了特别恐怖,我就觉得好奇,去看看服务情况,截图日志如下 关于jstat命令详情可以参考:https ...

  7. JVM菜鸟进阶高手之路九(解惑)

    转载请注明原创出处,谢谢! 在第八系列最后有些疑惑的地方,后来还是在我坚持不懈不断打扰笨神,阿飞,ak大神等,终于解决了该问题.第八系列地址:http://www.jianshu.com/p/7f7c ...

  8. JVM菜鸟进阶高手之路八(一些细节)

    转载请注明原创出处,谢谢! gc日志问题 查看docker环境的gc日志,发现是下面这种情况,很奇怪,一直怀疑是docker环境那里是否有点问题,并没有怀疑配置,之前物理机上面的gc日志都是正常那种. ...

  9. JVM菜鸟进阶高手之路七(tomcat调优以及tomcat7、8性能对比)

    转载请注明原创出处,谢谢! 因为每个链路都会对其性能造成影响,应该是全链路的修改压测(ak大神经常说全链路!).本次基本就是局域网,所以并没有怎么优化,其实也应该考虑进去的. Linux系统参数层面的 ...

随机推荐

  1. Qt程序打包(使用Enigma Virtual Box和BoxedApp Packer封包)

    一.使用单文件封包工具 单文件封包工具,顾名思义就是将可执行文件及其相关依赖打包成单个可执行文件的工具. 这里推荐两个单文件封包工具:Enigma Virtual Box和BoxedApp Packe ...

  2. LeetCode题解-----Majority Element II 摩尔投票法

    题目描述: Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The a ...

  3. 压缩 &amp; 解压缩 命令汇总:tar、zip &amp; unzip、

    1. tar命令详解     格式:tar [-cxtzjvfpPN] 文件与目录 -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五 ...

  4. ocp 1Z0-043 61-130题解析

    61. You are working in an online transaction processing (OLTP) environment. You realize that the sal ...

  5. 为什么样本方差(sample variance)的分母是 n-1?

    为什么样本方差(sample variance)的分母是 n-1? (補充一句哦,題主問的方差 estimator 通常用 moments 方法估計.如果用的是 ML 方法,請不要多想不是你們想的那樣 ...

  6. 测试heightlight

    var a = '综合型律师事务所'; if (a == '综合型律师事务所') { initradio('ls_classes', '综合型律师事务所'); } else { initradio(' ...

  7. ArcGIS 网络分析[1.1] 创建用于网络分析用的线类型shp文件[这个太基础了吧!]

    具体的准备,在上一篇就说过了,不再赘述. 阅读本篇前,需要的预备知识是:ArcGIS创建各种矢量数据的方法,了解地理坐标与投影坐标 本篇只创建单一的线数据,至于点数据,以后进行复杂的网络分析时再添加进 ...

  8. Ironic中pxe driver和agent driver的区别

    历史问题: 以pxe_ipmitool 和agent_ipmitool为例,看起来似乎前者不使用ironic-python-agent,后者使用,但是实际上两者都使用ironic-python-age ...

  9. python小白——进阶之路——day3天-———运算符

    (1)算数运算符:  + - * / // % ** (2)比较运算符:  > < >= <= == != (3)赋值运算符:  = += -= *= /= //= %= ** ...

  10. HTML中引入CSS的四种常用方法及各自的缺点

    在HTML中引入CSS的方法主要有四种,它们分别是行内式.内嵌式.链接式和导入式. 1.行内式 行内式是在标记的style属性中设定CSS样式.这种方式没有体现出CSS的优势,不推荐使用.格式如下: ...