java 虚拟机(jvm)基本概念和虚拟机参数配置

  • 虚拟机大致分为系统虚拟机(vmware,可运行完整操作系统的软件平台)和程序虚拟机(jvm,专门为执行当个计算机程序而设计),在上面运行的软件都被限制于虚拟机提供的资源中
  • 虚拟机的基本结构
虚拟机基本结构.png

1.类加载子系统:负责从文件系统或网络中加载class信息,存放到方法区,也就是一块内存空间

2.*方法区:存放类信息,常量信息,常量池信息,包括字符串字面量和数字常量等

3.*java堆:jvm启动的时候建立java堆,java程序最主要的内存工作区域,几乎所有的对象实例都放在java堆中,堆空间是所有线程共享的,

4.直接内存:java的nio库允许java程序使用直接内存,从而提高性能,通常直接内存速度会优于java堆,读写频繁的场合可能会考虑使用

5.*java栈:每个虚拟机线程都有一个私有的栈,线程栈在线程创建的时候被创建,线程栈中保存着局部变量,方法参数,java的方法调用,返回值等等

6.本地方法栈和java栈非常类似 ,但是本地方法栈用于java调用本地方法(通常使用c编写)

7.*java 自己的一套进行垃圾清理的机制,稍后详细说明

8.pc寄存器,每个线程的私有空间,jvm会为每个线程创建pc寄存器,在任意时刻,一个java线程总是在执行一个方法,这个方法称为当前方法,如果当前方法不是本地方法,pc寄存器就会执行当前正在被执行的指令,如果是本地方法,pc寄存器值为undefined,pc寄存器存放如当前执行环境指针,程序计数器,操作栈指针,计算的变量指针等

9.*虚拟机最核心的组件,负责执行虚拟机的字节码,一般会先进行编译成机器码后执行

带*的是重要部分

类加载之后一些信息(类信息,静态信息被存放于方法区中,快永久区Perm)
类被实例化之后,被存储到java堆中,一块内存空间
当我们使用对象的时候,其实用的是这块内存空间的引用
这个引用存放在java栈中

image.png
  • java堆详解
    • 几乎所有的对象都放在其中,java堆是自动化管理的,通过垃圾回收机制,垃圾对象会自动清理,不需要显示的释放
    • 根据垃圾回收机制的不同,java堆可能会有不同的结构,最常见的是将整个java堆分为新生代和老年代,新生代存放新生的对象或者年龄不大的对象,老年代则存放老年对象
    • 新生代分为eden区,s0区,s1区,s0和s1区也被称为from和to区域,他们是俩块大小相等并且可以互换角色的空间
    • 绝大多数情况下,对象首先分配在eden区,在一次新生代回收后,如果对象还存活,则会进入s0或者s1区(或者的原因是在任意时间s0和s1只能有一块在使用),之后每经过一次新生代回收,如果对象存活则它的年龄就加1,当对象达到一定年龄(阈值)后,则进入老年代(tenured区,表明在一定考量后,这个数据一直被引用,老年区的数据不会被频繁的回收,新生代则会被频繁回收)
    • s0和s1区存在的意义在于,这俩块区域的垃圾回收使用的是复制算法,核心思想是将内存空间分为俩块,每次只使用其中一块,垃圾回收时,将正在使用的内存中的存留对象复制到未被使用的内存块中去,之后去清除之前正在使用的内存块中的所有对象,反复去交换俩个内存的角色,完成垃圾收集。
  • java 栈
    • 线程私有的内存空间,一个栈一般有三部分组成:局部变量表,操作数栈和帧数据区
    • 局部变量表:用于保存函数的参数及局部变量
    • 操作数栈:主要保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间
    • 帧数据区:除了局部变量表和操作数栈之外,栈还需要一些数据来支持常量池的解析,帧数据区保存着常量池的指针,方便程序访问常量池,此外,当函数返回或者出现异常时,虚拟机必须有一个异常处理表,方便发送异常的时候找到异常的代码,因此异常处理表也是帧数据区的一部分。
  • java方法区
    • 和堆一样,方法区是一块所有线程共享的内存区域,它保存系统的类信息,比如类的字段,方法,常量池等,方法区的大小决定了系统可以保存多少个类,如果系统定义太多的类,导致方法区溢出。虚拟机同样会抛出内存溢出错误。方法区可以理解为永久区(Perm)
  • 虚拟机参数
    • 围绕堆,栈,方法区,垃圾回收机制 配置
    • 堆分配参数:
      • -xx:+PrintGC 虚拟机启动后,只要遇到GC就会打印日志
      • -xx:+UseSerialGC 配置串行回收器
      • -xx:+PrintGCDetails gc时可以查看详细信息,包括各个区的情况
      • -Xms java程序启动时初始堆大小
      • -Xmx java程序能获得的最大堆大小
      • -Xmn 设置新生代大小,这个参数对gc有较大影响,一般设置为整个堆大小的三分之一到四分之一左右
      • -XX:SurvivorRatio 设置新生代中eden空间和from或to空间的比例,如果等于3,说明eden区比上from或to区为3:1
      • -XX:NewRatio 设置新生代和老年代的比例
      • -XX:+PrintCommandLineFlags 可以将虚拟机的参数输出
      • 总结,实际工作中可以将初始堆大小和最大堆大小设置相等,这样可以减少程序运行时的垃圾回收次数,从而提高性能
      • GCdetails解读


        GCdetails
        • def new generation 新生代,分为eden区,from区,to区,后面几列是总空间,使用空间百分比,最后是内存地址
        • tenured generation 老年代,后面几列是总空间,使用空间百分比,最后是内存地址
        • compacting perm gen 永久区(perm)
      • 堆溢出处理
        • 如果堆空间不足,则会抛出内存溢出的错误(Out Of Memory,OOM),这类问题如果发生在生产环境,可能会引起严重的业务中断.
        • -XX:HeapDumpOnOutOfMemoryError,使用该参数可以再内存溢出时导出整个堆信息
        • -XX:HeapDumpPath 设置导出堆信息的存放路径,与上面的参数配合使用
        • 例子:
          -Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump
        • dump文件分析工具
        • 分析方法
        • 代码示例
        public static void main(String[] args) {
        
        //-Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump
        //堆内存溢出
        Vector v = new Vector();
        for(int i=0; i < 5; i ++){
            v.add(new Byte[1*1024*1024]);
          }
        
        }
        
      • 栈参数配置
        • -Xss 指定单个线程的最大栈空间,栈空间的大小直接决定了函数可调用的最大深度
        • 代码示例
        public class Test04 {
        
        //-Xss1m  
        //-Xss5m
        
        //栈调用深度
        private static int count;
        
        public static void recursion(){
            count++;
            recursion();
        }
        public static void main(String[] args){
            try {
                  recursion();
              } catch (Throwable t) {
          System.out.println("调用最大深入:" + count);
          t.printStackTrace();
            }
          }
        }
        
      • 方法区参数配置
        • 方法区保存系统的类信息
        • 默认情况下,-XX:MaxPermSize 为64MB,如果系统运行时产生大量的类,就需要设置一个相对合适的方法区,以免永久区内存溢出的问题
        • -XX:PermSize 初始化方法区大小
        • -XX:MaxPermSize 方法区最大大小
      • 直接内存参数配置
        • -XX:MaxDirectMemorySize,如果不设置,默认值为最大堆空间,即-Xmx,直接内存使用达到上限时,会触发垃圾回收,如果不能有效的释放空间,也会引起系统的OOM,
        • jdk1.7之后,不再关注这个参数,配不配都没什么大影响
  • Client和Server虚拟机工作模式
    • 只有在jdk1.7之前,jdk才分这俩个模式,1.7之后不再提供client模式,使用-client参数使用Client模式,使用-server使用Server模式,
    • 区别
      • Client模式启动较快,适用于测试,不追求系统的长时间使用性能
      • Server模式启动较慢,会对虚拟机的性能进行负载的系统性能信息收集和使用更复杂的算法对程序进行优化,长期运行性能远远快于client模式
  • 关于jvm的博客参考
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念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

推荐阅读更多精彩内容