初识JVM

 

 

 

 

   

 

一、程序计数器

  记住下一条jvm指令的执行地址,解释器会去程序计数器拿jvm指令。

 线程私有的,CPU会给每个线程分配时间片,时间片执行完会切换线程。

   唯一不会出现内存溢出的区域。

 

二、虚拟机栈

  线程运行需要的内存空间,每个线程都有一个栈。

   由多个栈帧组成,每个方法运行需要的内存(参数、局部变量、返回值),先入后出。

   每个线程只能有一个活动栈帧,就是正在执行的方法。

   垃圾回收不涉及栈内存。

   栈内存参数:-Xss 1024k。栈内存变大,总线程就会变少。

   方法内的局部变量如果没有逃离方法的作用范围,则是线程安全的。

   栈内存溢出错误:StackOverflowError

   案例:

    (一)CPU占用过高

      1、查看所有进程的cpu占用率,获取哪个进程占用cpu最高:top。

      2、查看某个进程的哪个线程占用cpu最高:ps H -eo pid,tid,%cpu | grep ${pid}。

      3、查看某个进程的所有线程详细信息:jstack ${pid}。

三、本地方法栈

  本地方法运行使用的内存,例如object.clone(),被native修饰的。

四、堆(heap)

  通过new创建的对象都会放在堆中,线程共享的,有垃圾回收机制。

   内存溢出异常:java.lang.OutOfMemoryError: java heap space。

   堆内存参数:-Xmx 8m

   堆内存诊断

    1、jps:查看当前系统中有哪些Java进程。

      jps -l

      (netstat -ano | findstr "8848")

    2、jmap:查看某进程的堆内存使用情况。堆内存快照信息。

      jmap -heap ${pid}

    3、jconsole:图形界面,多功能检测工具,可连续监测。

    4、jvisualvm:更好用的图形界面工具。

五、方法区

 

 

 

 

  所有线程共享,存储了跟类的结构相关的信息,虚拟机启动时创建。

   方法区内存参数:-XX:MaxPermSize=8m

   方法区内存溢出异常:java.lang.OutOfMemoryError: Metaspace。(1.8元空间)

             java.lang.OutOfMemoryError: PermGen space。(1.6永久代)

   1、运行时常量池

     二进制字节码(类的基本信息,常量池,类的方法定义,包含了虚拟机指令)

     获得虚拟机指令码:javap -v xxx.class

     常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数 类型、字面变量等信息。

     运行时常量池,常量池是*.class文件中的,当类被加载,它的常量池信息就会放到运行时常量池中,并把里边的符号地址变为真实地址

    1.1、StringTable(串池)

        运行时常量池中的字符串常量会被放到串池中,通过new关键字创建出的字符串对象不会放入串池。

         intern()方法可以将字符串对象尝试放入串池,如果有则不会放入,如果没有则放入,如论是否放入都会返回串池的对象。

       例:String x = new String("a") + new String("b");

         String s = x.intern();

         s是串池的对象。

         如果串池中已有“ab”,那么x不会被放入串池,但是s仍会得到串池的“ab”

         1.8中,如果串池中没有“ab”,那么x会被放入串池。

         1.6中,如果串池中没有“ab”,那么会将x的复制放入串池。

 

 

    1.2、StringTable位置

 

        1.6时放在永久代中,垃圾回收不及时,需要等老年代内存不足时才会收。

 

        1.8时放在堆内存中。

 

         验证:可以不断产生字符串放入串池,造成内存溢出,看抛出的异常时永久代溢出,还是堆内存溢出(注意:验证堆溢出需要添加参数-XX:-UseGCOverheadLimit。这是一个垃圾回收的限制机制,需要关闭)

 

    1.3、StringTable调优

 

        如果字符串常量很多,可以调大StringTable桶的数量:-XX:StringTableSize=20000

 

六、直接内存

  操作系统的内存,不受Java虚拟机管理。

   常见于NIO操作时,用于数据缓冲区。

   分配回收成本较高,但读写性能高。

   不受JVM内存回收管理。

   直接内存溢出异常:java.lang.OutOfMemoryError: Direct buffer Memory

 

原文链接:https://www.cnblogs.com/hmxs/p/11750141.html

posted @ 2019-12-05 10:53  你我皆牛马  阅读(125)  评论(0编辑  收藏  举报