一、成熟的系统调优
1、一定要绝对避免循环查数据库和缓存(PS:循环里面就不能有查询缓存,更不能有查询数据库的操作,因为循环的次数没法控制)

2、对于API接口的话,一般都是直接查缓存的,没有查数据库的

3、多用批量查询,少用单条查询,尽量一次查出来

4、对于使用阿里云,要留意一下相应产品的配置,该花的钱还是得花,同时,千万要记得正式环境中使用相应产品的内网地址

5、注意连接池大小(包括数据库连接池、Redis缓存连接池、线程池)

6、压测的机器上不要部署其它的服务,只跑待压测的服务,避免受其它项目影响;对于线上环境,最好一台机器上只部署一个重要的服务

7、没有用的以及被注释掉的代码,没有用的依赖最好及时清理掉

8、集群自不用说

9、一些监控类的工具工具可以帮助我们更好的定位问题,比如链路跟踪,这次项目中使用了PinPoint

10、如果技术上优化的空间已经非常小了,可以试着从业务上着手,用实际的数据说话,可以从日常的访问量,历史访问量数据来说服测试

11、每一次代码改动都有可能引入新的问题,因此,每次修改代码后都要回归测试一下(PS:每次修改完以后,我都会用几组不同的关键词搜索,然后比对修改前和修改后返回的数据是否一致,这个时候postman,以及Beyond compare就派上用场了)

12、关键的地方一定要多加点儿日志,方便以后排除问题,因为排查线上问题最主要还是靠日志

二、jvm 各种深入了解
引用计数算法
主流的Java虚拟机里面没有选用引用计数算法来管理内存,其中最主要的原因是它很难解决对象之间相互循环引用的问题。

可达性分析
GC roots对象向下搜索,搜索过的路径叫引用链,对象与GC roots 无关联,就被判定为为可回收对象。
java中,可作为GC roots的对象包括:虚拟机栈中引用的对象,方法区中类静态属性引用的对象,方法区中常量引用的对象。方法栈中JNI引用的对象。

强引用就是指在程序代码之中普遍存在的,类似“Object obj=new Object()”这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。

软引用是用来描述一些还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。在JDK 1.2之后,提供了SoftReference类来实现软引用。

弱引用也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK 1.2之后,提供了WeakReference类来实现弱引用。

虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK 1.2之后,提供了PhantomReference类来实现虚引用。

finalize()方法,可以对处于GC中的对象进行一次拯救,即使是在F-Queue的队列中,只要和任何一个对象建立关联,或是给某个类变量或对象赋值,那就会回到弱引用。当然这样的拯救只有一次,因为finallize()只能被调用一次。

回收方法区(永久代),这里面的方法回收效率比较低,在堆中,尤其新生代,一次回收可以回收大概70%-90%的空间,永久代的垃圾回收效率很低

永久代回收有两部分内容:1.废弃常量和无用的类 2.回收废弃常量(类似于java堆中的对象)。

满足三个条件会被回收:1.该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。 2.加载该类的classloader已经被回收。 3.该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

垃圾收集算法:
1.标记清除算法,最起初的收集算法,后续算法都是针对这个算法进行改进得到的。存在的问题:1.效率不高。2.空间问题,大多导致以后程序运行过程中需要分配大对象时,无法找到足够的内存,导致提前出发垃圾回收。
2.复制算法,把内存划分为大小相同的两块,每次使用一块。当一块内存用完,就将存活对象复制到另一块,再把已使用的那块清除。 优势:实现简单,运行高效。 缺点:这种算法直接把内存缩小一半,代价太高,当对象存活率较高时要进行较多复制操作,效率会变低。用途:现在商业虚拟机基本都是采用复制算法来回收新生代。
3.标记整理算法:根据老年代的特点,标记整理算法应运而生,过程和标记清楚算法一样,但后续是让所有存货对象向一端移动,然后直接清理其他内存。
4.分代收集算法:当前商业虚拟机都是采用分代回收,根据对象存活周期的不同将内存划分为几块。一般是把java堆分为新生代老年代,这样就可以根据各年代特点适当的收集算法。新生代-----复制算法,老年代-----标记清理或标记整理。

CMS收集器
HotSpot:实现中使用一组oopmap的数据结构来达到目的,在类被加载的时候,hotspot九八对象内的偏移量上的数据类型计算出来,在编译过程中,也会在特定的位置记录下栈和寄存器哪些引用。
作用:GC在扫描的时候就得知信息。

安全点: 在hotspot内容变化的时候,并没有为每个指令生成oopmap,只是在特定位置记录这些信息,这些位置就是安全点,程序并不是所有地方都停下来GC,只有在安全点位置才能暂停。安全点决定了程序是否具有程序长时间执行的特征。

hotspot虚拟机的垃圾收集器:
7种不同的分代收集器:
Serial收集器 :jdk1.3.1之前新生代唯一选择.单线程收集器,他在进行垃圾收集时,所有工作县城都需要暂停,直到他收集结束。优点:简单高效,对于单个cpu环境来说,serial收集器没有其他线程开销,最高单线程收集效率。因为停顿时间可以控制在几十毫秒以内,不频繁发生完全可以接受,所以知道1.7 Serial收集器还是client模式下的虚拟机最好选择。

ParNew收集器: 他是Serial收集器的多线程版本。他是许多运行在server模式下的虚拟机首选的新生代收集器。有一个重要原因,目前只有它与CMS收集器配合工作。

Parallel Scavenge收集器: 新生代收集器,采用复制算法的收集器,并行多线程收集器。PS收集器的目标是达到一个可控制的吞吐量(Throuhtput)。所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值。PS收集器又被称为吞吐量优先级收集器,它还有一个特别的参数:+UseAdaptiveSizePolicy参数。这个参数打开之后,就不用手动指定新生代大小,eden与survivor区的比例,晋升老年代对象年龄等细微参数。虚拟机会自动调节被称为GC自适应。自适应策略也是PS收集器和ParNew收集器一个重要区别。

Serial Old收集器: 是Serial老年代版本,同样是一个单线程收集器,使用标记整理算法。

Parallel Old收集器: Parallel Scavenge收集器老年版本,使用多线程和标记整理算法。

CMS收集器: 是一种以获取最短回收停顿时间为目的的收集器。希望停顿时间最短,来获得更好的用户体验。 使用标记清除算法,运作比较复杂,分为4个步骤分别是:初始标记,并发标记,重新标记,并发清除。1.初始标记,仅仅标记一下GC roots关联到的对象,速度很快,并发标记阶段就是进行GC rootsTracing的过程,二重新标记阶段是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的一部分对象的标记记录。优点:并发收集,低停顿,用户体验好。 缺点:1.CMS收集器对CPU资源非常敏感。导致一部分线程被占用,使应用程序变慢,吞吐量降低。2.CMS收集器无法处理浮动垃圾(并发清理阶段用户线程还在运行,这段时间就可能产生新的垃圾,新的垃圾在此次GC无法清除,只能等到下次清理)。3.基于标记清除算法,结束时会产生大量空间碎片垃圾。

G1收集器: 当今收集器技术发展最前沿成果之一。特点:1.并行与并发,通过并发的方式保持java运行不受GC影响。2.分代收集,根据存活时间来获取最好的收集效果。3.空间整合,G1收集器整体来看是基于标记整理算法,局部上来看是基于复制算法,意味着运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。有利于长时间运行,分配大对象时不会因为无法找到连续内存空间而提前GC。4.可预测的停顿,这是比CMS一大优势,能让使用者明确指定在一个长度的时间片内,这几乎已经是实时Java的垃圾收集器特征。

内存分配和回收策略:
1.对象优先在Eden分配
2.大对象直接进入老年代
3.长期存活的对象将进入老年代
4.动态对象年龄判断
5.分配担保

JVM原理自总结的更多相关文章

  1. 学习重点:1、金典的设计模式在实际中应用2、JVM原理3、jui源代码

    学习重点:1.金典的设计模式在实际中应用 2.JVM原理 3.jui源代码

  2. JVM原理分析

    1 什么是JVM? JVM是Java Virtual Machine(Java虚拟机)的缩写,是通过在实际的计算机上仿真模拟各种计算机功能来实现的.由一套字节码指令集.一组寄存器.一个栈.一个垃圾回收 ...

  3. Java面试之JVM原理总结

    1.什么是JVM? 答:JVM是Java Virual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,他是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟计算机功能来实现 ...

  4. 说说JVM原理?内存泄漏与溢出的区别?何时产生内存泄漏?

    1.JVM原理 JVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个java实现跨平台的最核心的部分,所有的Java程序会首先被编译为.class的类文件,这种类文件可以 ...

  5. JVM原理及内存溢出

    JVM原理及内存溢出

  6. Java程序员必了解的JVM原理以及虚拟机的运行过程

    JVM概念 虚拟机:指以软件的方式模拟具有完整硬件,VM概念 虚拟机:指以软件的方式模拟具有完整硬件系统功能.运行在一个完全隔离环境中的完整计算机系统 ,是物理机的软件实现.常用的虚拟机有VMWare ...

  7. (转)JVM原理讲解和调优

    背景:jvm实际调优在面试时候经常被问到,所以有必要认真总结一番. 转自:JVM原理讲解和调优 四.JVM内存调优 首先需要注意的是在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存 ...

  8. Java 面试题 三 <JavaWeb应用调优线程池 JVM原理及调优>

    1.Java Web应用调优线程池 不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文由浅入深,介 ...

  9. jvm出现OutOfMemoryError时处理方法/jvm原理和优化参考

    The heap stores all of the objects created by your java program.The heap's contents is monitored by ...

  10. 转载:把你的精力专注在java,jvm原理,spring原理,mysql锁,事务,多线程,大并发,分布式架构,微服务,以及相关的项目管理等等,这样你的核心竞争力才会越来越高

    https://developer.51cto.com/art/202001/608984.htm 把你的精力专注在java,jvm原理,spring原理,mysql锁,事务,多线程,大并发,分布式架 ...

随机推荐

  1. Android四种数据存储方式

    一.SharedPreference数据存储篇 1.作用范围 (1).它是一种轻型的数据存储方式 (2).本质是基于XML文件存储key-value键值对数据 (3).通常用来存储一些简单的配置方式 ...

  2. Redux其实很简单(原理篇)

    在这一篇文章中,笔者将带大家编写一个完整的Redux,深度剖析Redux的方方面面,读完本篇文章后,大家对Redux会有一个深刻的认识. 核心API 这套代码是笔者阅读完Redux源码,理解其设计思路 ...

  3. C++命令行画心形<转载>

    #include <stdio.h> int main() { for (float y = 1.5f; y > -1.5f; y -= 0.1f) { for (float x = ...

  4. Python任意网段Web端口信息探测工具

    此篇关于多线程工具的文章,非常适合新手学习,工具效率也挺高的,代码也比较完善,如题. 本文作者:i春秋签约作家——Aedoo 0×00 前言 笔者前一段时间发布了原创文章,“[Python黑客] Py ...

  5. 北大POJ题库使用指南

    原文地址:北大POJ题库使用指南 北大ACM题分类主流算法: 1.搜索 //回溯 2.DP(动态规划)//记忆化搜索 3.贪心 4.图论 //最短路径.最小生成树.网络流 5.数论 //组合数学(排列 ...

  6. 配置阿里云ESC服务器部署项目

    第一次SSH登录 ECS 服务器: 打开命令行终端(git),键入: > ssh root@39.108.54.110 输入实例密码,进入服务器环境. 配置 root 及应用账号权限 新增管理员 ...

  7. 【bug】安卓浏览器键盘输入改变弹出层的定位

    bug描述 在安卓浏览器中,有一个在页面底部的弹出层表单,样式如下: .popup { position: absolute; bottom: 0; } 当在这个弹出层输入内容,键盘自动弹出,弹出层的 ...

  8. MySQL实例crash的案例分析

    [作者] 王栋:携程技术保障中心数据库专家,对数据库疑难问题的排查和数据库自动化智能化运维工具的开发有强烈的兴趣. [问题描述] 我们生产环境有一组集群的多台MySQL服务器(MySQL 5.6.21 ...

  9. iOS--线程的创建

    1.获取当前线程 NSThread *current=[NSThread currentThread]; 2.获取主线程的另外一种方式 NSThread *main=[NSThread mainThr ...

  10. python3中文件操作及编码

    #之前一直没明白文件处理中的w和wb的区别到底是什么,#在看过视频后才知道,原来在linux里面是没有区别的,#但是在windows里面就能够看出区别来了#下面来个例子: with open(&quo ...