• JVM性能优化


    https://www.cnblogs.com/heihaozi/p/14950212.html

    思路: 可以说一下jps,top ,jstack这几个命令,再配合一次排查线上问题进行解答。

    参考答案:

    • 输入jps,获得进程号。
    • top -Hp pid 获取本进程中所有线程的CPU耗时性能
    • jstack pid命令查看当前java进程的堆栈状态
    • 或者 jstack -l > /tmp/output.txt 把堆栈信息打到一个txt文件。
    • 可以使用fastthread 堆栈定位,fastthread.io/

    虚拟机栈是每个线程私有的,线程在运行时,在执行每个方法的时候都会打包成一个 栈帧,存储了 局部变量表,操作数据栈,动态链接,方法出口等信息,然后放入栈。每个时刻正在执行的当前方法就是虚拟机栈顶的栈桢。方法的执行就对应着栈帧在虚拟机栈中入栈和出栈的过程。

    方法区

    主要存储类信息、常量池、静态变量、即时编译期编译后的代码等数据。

    一、内存溢出

    内存溢出的原因:程序在申请内存时,没有足够的空间。

    1. 栈溢出

    方法死循环递归调用(StackOverflowError)、不断建立线程(OutOfMemoryError)。

    2. 堆溢出

    不断创建对象,分配对象大于最大堆的大小(OutOfMemoryError)。

    3. 直接内存

    JVM 分配的本地直接内存大小大于 JVM 的限制,可以通过-XX:MaxDirectMemorySize 来设置(不设置的话默认与堆内存最大值一样,也会出现OOM 异常)。

    4. 方法区溢出

    一个类要被垃圾收集器回收掉,判定条件是比较苛刻的,在经常动态生产大量 Class 的应用中,CGLIb 字节码增强,动态语言,大量 JSP(JSP 第一次运行需要编译成 Java 类),基于 OSGi 的应用(同一个类,被不同的加载器加载也会设为不同的类),都可能会导致OOM。

    三、内存溢出和内存泄漏辨析

    • 内存溢出:实实在在的内存空间不足导致。
    • 内存泄漏:该释放的对象没有释放,常见于使用容器保存元素的情况下。

    如何避免

    • 内存溢出:检查代码以及设置足够的空间。
    • 内存泄漏:一定是代码有问题,往往很多情况下,内存溢出往往是内存泄漏造成的。

    四、了解MAT

    mat是一个内存泄露的分析工具。

    1. 浅堆和深堆

    • 浅堆(Shallow Heap):是指一个对象所消耗的内存。
    • 深堆(Retained Heap):这个对象被 GC 回收后,可以真实释放的内存大小,也就是只能通过对象被直接或间接访问到的所有对象的集合。通俗地说,就是一个对象包含(引用)的所有对象的大小,如图:

    参数说明:

    • -Xms5m 堆初始大小5M
    • -Xmx5m 堆最大大小5M
    • -XX:+PrintGCDetails 打印gc日志详情
    • -XX:+HeapDumpOnOutOfMemoryError 输出内存溢出文件
    • -XX:HeapDumpPath=D:/oomDump/dump.hprof 内存溢出文件保存位置,此文件用于MAT分析

    所有的工具都在jdk的安装bin目录下,比如我的在C:My Program FilesJavajdk1.8.0_201in

    其中一般情况命令行在线上服务器上使用,可视化工具在本地使用,当然如果你的线上服务器允许远程的话也可以使用可视化工具。

    https://www.cnblogs.com/itwxe/p/14884361.html

    一般有两种方式(引用计数法、可达性分析),JVM使用的是可达性分析

    2. 可达性分析

    来判定对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的。

    作为 GC Roots 的对象包括下面几种:

    • 当前虚拟机栈中局部变量表中的引用的对象
    • 方法区中类静态属性引用的对象
    • 方法区中的常量引用的对象

    3. finalize

    Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize(),可以完成对象的拯救(不被回收),但是不能保证一定不被回收,说白了就是没啥用,一个坑。

    三、各种引用(Reference)

    Reference 中存储的数据代表的是另一块内存的起始地址。

    1. 强引用

    一般的 Object obj = new Object() ,就属于强引用。

    (如果有 GCroots 的强引用)垃圾回收器绝对不会回收它,当内存不足时宁愿抛出 OOM 错误,使得程序异常停止,也不会回收强引用对象。

    2. 软引用

    SoftReference垃圾回收器在内存充足的时候不会回收它,而在内存不足时会回收它。

    所以软引用一般用来实现一些内存敏感的缓存,只要内存空间足够,对象就会保持不被回收掉

    3. 弱引用 WeakReference

    垃圾回收器在扫描到该对象时,无论内存充足与否,都会回收该对象的内存

    实际应用,如 WeakHashMap、ThreadLocal。

    4. 虚引用 PhantomReference

    幽灵引用,最弱,被垃圾回收的时候收到一个通知,如果一个对象只具有虚引用,那么它和没有任何引用一样,任何时候都可能被回收。

    虚引用主要用来跟踪对象被垃圾回收器回收的活动。

    四、GC

    1. Minor GC

    • 特点: 发生在新生代上,发生的较频繁,执行速度较快。
    • 触发条件: Eden 区空间不足/空间分配担保。

    1. 复制算法(Copying)

    2. 标记-清除算法(Mark-Sweep)

    3. 标记-整理算法(Mark-compact)

     

    6. G1

    G1相比较CMS的改进

    • 基于标记-整理算法, 不会产生空间碎片,分配大对象时不会无法得到连续的空间而提前触发一次full gc 。
    • 停顿时间可控: G1可以通过设置预期停顿时间(Pause time)来控制垃圾收集时间,但是这个预期停顿时间G1只能尽量做到,而不是一定能做到

    2. Full GC

    • 特点:主要发生在老年代上(新生代也会回收),较少发生,执行速度较慢。
    • 触发条件:
      • 调用 System.gc() 。
      • 老年代区域空间不足。
      • 空间分配担保失败。
      • JDK 1.7 及以前的永久代(方法区)空间不足。
    小蚊子大人
  • 相关阅读:
    Appium学习实践(二)Python简单脚本以及元素的属性设置
    Appium学习实践(三)测试用例脚本以及测试报告输出
    Appium学习实践(一)简易运行Appium
    Appium学习实践(四)结构优化
    js中对小数取整的函数
    C#基础 面试中常出现的问题
    repeater中的删除按钮实现
    js对fck编辑器取值 赋值
    jQuery对select操作
    进制转换(二进制 八进制 十进制 十六进制)
  • 原文地址:https://www.cnblogs.com/ywsheng/p/14948610.html
Copyright © 2020-2023  润新知