jvm 架构及调优

jvm 架构及优化

写在前面

先看一下知乎上一个有趣的问题:

Java工程师面试的时候,总是提问一些jvm如何优化的问题,这些真的在开发中有用吗,工作七年了项目中从来没有用过,并且我获得过多次优秀员工,望做过优化的大牛解答?

答一:
JVM优化肯定是有用的,可能只是题主没有遇到过这方面的需求。比如一些GC机制会引起JVM的Stop The World,也就是所有工作线程都会停下来等待GC完成。对于一些对延迟比较敏感的程序来说,这一停顿达到一百甚至是几十毫秒的时候就是难以接受的。为了解决这类问题,就需要对JVM的参数做适当的调整。比如调整堆的大小,选择合适的垃圾回收器,控制对象晋升老年代的速度等等。

作者:谢知恒

链接:https://www.zhihu.com/question/40913700/answer/88862720

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

答二:
对于楼主这种情况也是可以理解的,以前我在传统行业做行业软件的时候也是对jvm一无所知,觉得一点用没有,面试问只是装逼而已。后来踏入互联网行业才明白,这是必须掌握的,而且经常会用,遇到tp99间断性的提高,这种情况首先就会去看是否是fullGC引起的,还有就是内存溢出之类的问题,不了解jvm怎么去解决这类问题。当然传统行业软件,用户量少可能不会去监控性能,遇到内存溢出可能也就重启解决了,不了了之,下次再重启。然而,对于java开发人员来说,jvm就是一座商厦,我们在里面开店,连消防栓在哪里都不知道,哪天着火了,应急楼梯也不知道在哪里,只能坐着哭?所以还是建议楼主了解一下jvm,推荐看《深入理解java虚拟机》

作者:周易

链接:https://www.zhihu.com/question/40913700/answer/138011891

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

从上面两段回答中可以看出来,熟悉jvm架构和调优意义在于出了性能问题后,多给程序员留了一条退路。

jvm 架构

jvm架构

首先先附上一张jvm架构图。
上图中主要由几个部分组成:

  • 类加载器(ClassLoader):在JVM启动时或者在类运行时将需要的class加载到JVM中。每当运行一个
    java 程序时,就会首先动态创建相应的jvm instance(启动三个程序,就会有三个jvm实例,这点和golang runtime非常类似),然后将该程序的所有类文件通过类加载器加载到jvm中。
  • 执行引擎:负责执行class文件中包含的字节码指令.执行引擎是java 虚拟机模拟运行的运算引擎,基本起到了翻译的作用。
    有两种翻译的方式:
    • 一句话一句话翻译。也就是解释执行。将程序计算器中指向的待执行的java字节码翻译为cpu可以运行的机器指令。
    • 一次性翻译。即编译执行。通过JIT(just in time)一次性将所有的字节码翻译完成。
  • 内存区(也叫运行时数据区):是在JVM运行的时候操作所分配的内存区。从上图中可以看出,主要分为五个部分。
  • 本地库接口,本地方法库:操作系统所有,用于处理jvm的native code和通过jit编译后的本地代码。

jvm 执行引擎

关于jvm的执行引擎,它并不是真正软件模拟实现了cpu,最终所有计算机上的运算都是由cpu执行机器指令来处理。

有个问题?jvm执行引擎和本地代码关系如何?本地代码还需要过jvm执行引擎吗?

猜测答案:应该是需要过的,jvm封装了所有的代码,管理着程序执行的结果。

关于执行引擎采用哪种方式来运行,经验如下:

用JIT编译器来编译代码所花的时间要比用解释器去一条条解释执行花的时间要多。因此,如果代码只被执行一次的话,那么最好还是解释执行而不是编译后再执行。因此,内置了JIT编译器的JVM都会检查方法的执行频率,如果一个方法的执行频率超过一个特定的值的话,那么这个方法就会被编译成本地代码。

jvm 内存

从jvm 架构可以看出,jvm内存主要分为五部分:

  • 方法区(Method Area):用于存储类结构信息的地方,包括常量池、静态变量、构造函数等。虽然JVM规范把方法区描述为堆的一个逻辑部分, 但它却有个别名non-heap(非堆),所以大家不要搞混淆了。方法区还包含一个运行时常量池。
  • java堆(Heap):存储java实例或者对象的地方。这块是GC的主要区域。从存储的内容我们可以很容易知道,方法区和堆是被所有java线程共享的。
  • java栈(Stack):java栈总是和线程关联在一起,每当创建一个线程时,JVM就会为这个线程创建一个对应的java栈。在这个java栈中又会包含多个栈帧,每运行一个方法就创建一个栈帧,用于存储局部变量表、操作栈、方法返回值等。每一个方法从调用直至执行完成的过程,就对应一个栈帧在java栈中入栈到出栈的过程。所以java栈是现成私有的。
  • 程序计数器(PC Register):用于保存当前线程执行的内存地址。由于JVM程序是多线程执行的(线程轮流切换),所以为了保证线程切换回来后,还能恢复到原先状态,就需要一个独立的计数器,记录之前中断的地方,可见程序计数器也是线程私有的。
  • 本地方法栈(Native Method Stack):和java栈的作用差不多,只不过是为JVM使用到的native方法服务的。

java 堆存放对象实例。
java 栈存放普通的变量及其它类型的信息。
这样的好处是对象通常占有内存很大,但个数少。栈里存放的东西个数多,占用内存少。对象是垃圾回收的主战场。
所以要分出栈和堆来。

jvm调优

传统的软件开发过程中不需要考虑到jvm调优的内容,主要出于以下的几点考虑:

  • 性能不是生命线。
  • 系统出问题后可以采取其它的方式进行处理,例如停机,停机后再恢复,受影响不大。

而在互联网领域,上述两个问题就变为比较严重的问题。
为了留住用户,响应时间和吞吐量就会成为必须去解决的问题。而jvm性能瓶颈主要在与jvm自带的垃圾回收机制。

内存分配机制

静态内存&动态内存

Java的内存分配原理与C/C++不同,C/C++每次申请内存时都要malloc进行系统调用,而系统调用发生在内核空间,每次都要中断进行切换,这需要一定的开销,

而Java虚拟机是先一次性分配一块较大的空间,然后每次new时都在该空间上进行分配和释放,减少了系统调用的次数,节省了一定的开销,这有点类似于内存池的概念;二是有了这块空间过后,如何进行分配和回收就跟GC机制有关了。

java一般内存申请有两种:

  • 静态内存.编译时就能够确定的内存就是静态内存,即内存是固定的,系统一次性分配,比如int类型变量;java栈、程序计数器、本地方法栈都是线程私有的,线程生就生,线程灭就灭,栈中的栈帧随着方法的结束也会撤销,内存自然就跟着回收了。我们不需要管的。
  • 动态内存。动态内存分配就是在程序执行时才知道要分配的存储空间大小,比如java对象的内存空间。所以这几个区域的内存分配与回收是确定的,但是java堆和方法区则不一样,我们只有在程序运行期间才知道会创建哪些对象,所以这部分内存的分配和回收都是动态的。一般我们所说的垃圾回收也是针对的这一部分。

总之Stack的内存管理是顺序分配的,而且定长,不存在内存回收问题;而Heap 则是为java对象的实例随机分配内存,不定长度,所以存在内存分配和回收的问题;

新生代&老生代

在 Java 中,堆被划分成两个不同的区域:

  • 新生代 ( Young )。 生命周期较短。
  • 老年代 ( Old )。生命周期较长。
  • 永久代。很少被讨论。

新生代 ( Young ) 又被划分为三个区域:

  • Eden
  • From Survivor
  • To Survivor。

GC机制简述

JVM 使用的GC算法是什么?

分代收集:即将内存分为几个区域,将不同生命周期的对象放在不同区域里。GC根据用途来说有以下三种:

  • GC(或Minor GC):收集 生命周期短的区域(Young area)。Minor GC会把Eden中的所有活的对象都移到Survivor区域中,如果Survivor区中放不下,那么剩下的活的对象就被移到Old generation 中。

  • Full GC (或Major GC):基于标记-清除算法,收集生命周期短的区域(Young area)和生命周期比较长的区域(Old area)对整个堆进行垃圾收集。

  • Major GC :清理永久代。

GC 效率也会比较高,我们要尽量减少 Full GC 的次数。

在minor Gc 与Full Gc执行机制上,都提供了三种选择:

  • 串行GC(SerialGC)
  • 并行回收GC(ParallelScavenge
  • 并行GC(ParNew)

可以根据具体的需要选择相应的GC。

GC的调整是在吞吐量和响应时间上做一个平衡。

jvm调优简述与工具

怎样调优?
有何工具?
Jvm调优工具有以下几种:

  • Jconsole : jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用。对垃圾回收算法有很详细的跟踪。详细说明参考这里
  • JProfiler:商业软件,需要付费。功能强大。详细说明参考这里
  • VisualVM:JDK自带,功能强大,与JProfiler类似。推荐。

关于调优这块在实际业务中碰到这类的问题再进行具体分析。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,888评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,677评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,386评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,726评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,729评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,337评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,902评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,807评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,349评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,439评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,567评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,242评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,933评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,420评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,531评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,995评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,585评论 2 359

推荐阅读更多精彩内容

  • 1.一些概念 1.1.数据类型 Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始...
    落落落落大大方方阅读 4,545评论 4 86
  • JVM内存模型Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是: ...
    光剑书架上的书阅读 2,522评论 2 26
  • 原文阅读 前言 这段时间懈怠了,罪过! 最近看到有同事也开始用上了微信公众号写博客了,挺好的~给他们点赞,这博客我...
    码农戏码阅读 5,993评论 2 31
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,277评论 11 349
  • 周末,在朋友家小住, 觉得简单但很满足,于是对朋友说:“在你这里住得不想走了,有好电影、好音乐、好书,还有一张便于...
    微笑的秧秧阅读 1,333评论 11 43