性能优化之基础资源cpu&内存(JVM)

本章主要介绍计算机的一些基础资源以及操作系统处理后的一些基础资源。

主要包括

  • cpu
  • 内存
  • 磁盘
  • 网络
  • 线程

本章会介绍这些资源的一些原理,介绍如何查看资源的数量,使用情况,对性能和整体计算机执行的一些影响。
本章很多内容都基于linux,不是特殊说明,就是针对linux的情况。可能在其它操作系统不一定适用。

另外还会对jvm之上的一些内容做特殊说明,因为大家很大的一些积累都在jvm之上,内部的系统基本也建立在jvm上。

  • jvm 指令
  • jvm 内存使用

cpu

cpu是计算机里最重要的资源,没有之一,并且在性能优化领域,也是最需要理解的内容。

在代码执行方面,cpu执行代码的最终指令,调度资源,操作内存,对完成一个任务的各个方面都有较大影响。

首先,在linux中查看cpu信息的基础指令是看cpu的硬件信息

cat /proc/cpuinfoo

可以看到cpu的核数,单核的频率,以及cpu支持的一些特性。

另外一个最多接触到的内容是 load average 三联组,在很多命令中都会体现,w,top,uptime等等。

分别表示最近1,5,15分钟的cpu使用压力。

关于cpu的使用%比,和cpu load,是两个相似又有不同的概念,在linux里,cpu%也有不同的解释,具体不同,见下方解释。

cpu使用%

  • top的最上面的部分
  • us 总体用户态cpu的使用%
  • sy 核心态
  • wa cpu等待,这里主要是等待io
    • iowait的产生是因为cpu处理的请求除了iowait之外就没有其它事情可以做了,或者说所有的线程,如果runable状态的都在做io操作
  • id 空闲
  • top中线程上看到的cpu%,是1个cpu对应100%,上面说的几个值是所有cpu对应100%,所以在多cpu的时候,会看到线程已经大于200%了,而上面的数据还很正常

load

  • 主要关注的是等待执行的队列的长度
  • 因为等待的队列长,造成的上下文切换也较多
    • 上下文切换可以看vmstat的cs部分

      •  一般vmstat工具的使用是通过两个数字参数来完成的,第一个参数是采样的时间间隔数,单位是秒,第二个参数是采样的次数,如:
      • 具体vmstat参数请自行google,或者度娘详情,这儿不做介绍
  • 另外如果cpu使用和load不同步,需要注意任务大大小。
    • 如果任务太小,会造成load》cpu%
    • 任务很大,cpu%》load
  • 关于load的值,也是要看cpu的核数,如果load数<=cpu数,表明某个时间段,没有任何任务是需要等待cpu资源才能开始处理的

内存

内存管理

这里主要介绍java虚拟机内部的内存管理。

jvm相关的内存主要分为以下几个部分

  • 方法栈 & 本地方法栈

    • 放大调用堆栈
  • 方法区
    • perm区,类信息元数据,静态对象等
    • 各种对象,new出来的东西
  • Native Memory(C Heap)
    • NIO的DirectBuffer
    • JNI
    • Compile  jit的结果

关键部分堆,按照现在的流行用法又分为

  • 新生代

    • Eden
    • S0
    • S1
  • 老年代

通过java参数,-Xmn可以调整新生代和老年代的大小
-XX:SurvivorRatio 可以调整Eden和S0S1的大小  S1=S0=mn/(SurvivorRatio+2)
-XX:MaxTenuringThreshold 对象在新生代存活的次数

-XX:MaxPermSize 可以调整perm区的大小
-Xss 可以调整方法栈的大小
-XX:MaxDirectMemorySize 可以调整Native Memory的大小

对象在Eden和s0以及老年代的存活一般策略,有例外。

  • new的时候在Eden,Eden满了,做一次YGC
  • 剩余对象放在在S0,清空Eden
  • 继续new,在Eden,Eden满了的时候,做YGC和S0一起做
  • 剩余对象在S1,这个时候,如果有对象在S0或者S1的次数大于MaxTenuringThreshold,这种对象放到Old区
  • 如果S1满了,所有对象到Old区
  • 如果Old区满了,则做fullgc
  • 依次循环

从使用上来说,最满意的方式是,经过几轮往old区晋升后,old区趋于不变。old区可以存放一些类似于缓存对象等等,容器相关对象等需要长期生存的对象。
Eden区和S0区够大,对象在新生代的存活时间不超过MaxTenuringThreshold。

基本做法,从开始就把对象往2个方向设计,是长期存活,或者短期存活。
合理设计新老生代大小。

对内存的优化,其实主要也体现在对cpu时间使用上,包含对象创建,老对象地址查找,对象垃圾收集,我们能做的是尽量少的创建对象,以及尽量少的垃圾收集,对于老对象地址的查找,暂时没有太多方法。

内存泄露

内存泄露,主要涉及到垃圾收集方法,现在流行的方法,是通过一些gcroot,来查找所有在用的对象,保存下来,其它对象都gc掉。

一般的gcroot有以下一些类型的对象

  • 当前存活的线程
  • 当前load的class
  • 存活的线程栈上的方法参数和本地参数
  • jni相关的global信息,以及相关栈上的方法参数,和本地参数
  • 同步的时候用的monitor对象
  • jvm的一些保留对象

如果有对象和这些相关的内容一直没有脱开关系,就有可能造成内存溢出。

一些典型的案例

  • 某个应用使用了一个类上的static map 做为缓存,key越来越多,最后就溢出了
  • 某个应用需要动态创建类型,如果这个对象创建一直使用同一个classloader,最后就会造成load的class越来越多,perm区溢出

需要区分对待内存溢出和内存使用过快,以及相关的转化过程

查看配置的主要方式

通过以下命令,可以看到你想要的配置,如果有其它参数在线上有配置的,直接加上参数。

java -server -Xmx128m -XX:+PrintFlagsFinal | grep MaxHeapSize

jvm 指令

java的代码在编译成class之后,就变成了jvm可以认识的特定格式了,具体格式,大家可以参考jvm虚拟机规范。

最近的几个版本,可以在这里拿到,这个地址上也包好java语言的规范,2者的区别是,一个是介绍如何编写java虚拟机的,一个是介绍如何编写java代码的。

http://docs.oracle.com/javase/specs/

抛开jit,java就是针对jvm指令,一步一步执行的。

jvm对编译前的语言没有任何要求,所有现在有很多基于jvm的其它语法的语言,如scala,groovy,jruby等等。

而asm就是一套认识jvm指令,或者说是class文件格式的工具。

jvm在加载class的时候,提供了某些功能,可以让人为修改class对象,或者说是修改class最终加载到jvm的字节流。

通过asm对class字节流的修改,修改了class实际执行的行为,而达到我们的目的。

一些简单的例子

  • 通过解析class,在特定的一些类的方法前后,加入代码,方法的开头记录一个当前时间,方法结束的时候,再做一个当前时间和之前记录的时间的比较,就是一个简单执行时间profiler
  • 通过对某个类的构造器方法的监控,可以找到所有这个类以及子类的创建数量
  • 通过对类方法的调用的参数和结果返回,可以记录方法的一些具体参数和结果,用于debug,或者确认方法是否被调用过
  • 通过对方法开头的拦截,直接返回自己想要的结果,就是一个调用mock框架

《~~~后续更精彩~~~》

时间: 2024-09-30 10:40:55

性能优化之基础资源cpu&内存(JVM)的相关文章

Spark性能优化指南——基础篇(转)

http://mp.weixin.qq.com/s?__biz=MjM5NDMwNjMzNA==&mid=2651805828&idx=1&sn=2f413828d1fdc6a64bdbb25c51508dfc&scene=2&srcid=0519iChOETxAx0OeGoHnm7Xk&from=timeline&isappinstalled=0#rd Spark性能优化指南--基础篇 优才网 2016-05-18 前言 在大数据计算领域,Spar

C++应用程序性能优化(五)——操作系统的内存管理

C++应用程序性能优化(五)--操作系统的内存管理 一.操作系统内存管理简介 长期以来,在计算机系统中,内存都是一种紧缺和宝贵的资源,应用程序必须在载入内存后才能执行.早期,在内存空间不够大时,同时运行的应用程序的数量会受到很大的限制,甚至当某个应用程序在某个运行时所需内存超过物理内存时,应用程序就会无法运行.现代操作系统(Windows.Linux)通过引入虚拟内存进行内存管理,解决了应用程序在内存不足时不能运行的问题.本质上,虚拟内存就是要让一个程序的代码和数据在没有全部载入内存时即可运行.

Spark性能优化指南——基础篇

前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作,应用范围与前景非常广泛.在美团•大众点评,已经有很多同学在各种项目中尝试使用Spark.大多数同学(包括笔者在内),最初开始尝试使用Spark的原因很简单,主要就是为了让大数据计算作业的执行速度更快.性能更高. 然而,通过Spark开发出高性能的大数据计算作业,并不是那么简单的.如果没有对Spar

美团Spark性能优化指南——基础篇

http://tech.meituan.com/spark-tuning-basic.html 前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作,应用范围与前景非常广泛.在美团?大众点评,已经有很多同学在各种项目中尝试使用Spark.大多数同学(包括笔者在内),最初开始尝试使用Spark的原因很简单,主要就是为了让大数据计算作业的执行速度更快.性

【转载】 Spark性能优化指南——基础篇

前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能复用同一个RDD 原则三:对多次使用的RDD进行持久化 原则四:尽量避免使用shuffle类算子 原则五:使用map-side预聚合的shuffle操作 原则六:使用高性能的算子 原则七:广播大变量 原则八:使用Kryo优化序列化性能 原则九:优化数据结构 资源调优 调优概述 Spark作业基本运行原理 资源参数调优 写在最后的话 前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的

Spark性能优化指南——基础篇转

前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作,应用范围与前景非常广泛.在美团•大众点评,已经有很多同学在各种项目中尝试使用Spark.大多数同学(包括笔者在内),最初开始尝试使用Spark的原因很简单,主要就是为了让大数据计算作业的执行速度更快.性能更高. 然而,通过Spark开发出高性能的大数据计算作业,并不是那么简单的.如果没有对Spar

Spark性能优化指南--基础篇

前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能复用同一个RDD 原则三:对多次使用的RDD进行持久化 原则四:尽量避免使用shuffle类算子 原则五:使用map-side预聚合的shuffle操作 原则六:使用高性能的算子 原则七:广播大变量 原则八:使用Kryo优化序列化性能 原则九:优化数据结构 资源调优 调优概述 Spark作业基本运行原理 资源参数调优 写在最后的话 前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的

Spark性能优化指南——基础篇(转载)

前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作,应用范围与前景非常广泛.在美团•大众点评,已经有很多同学在各种项目中尝试使用Spark.大多数同学(包括笔者在内),最初开始尝试使用Spark的原因很简单,主要就是为了让大数据计算作业的执行速度更快.性能更高. 然而,通过Spark开发出高性能的大数据计算作业,并不是那么简单的.如果没有对Spar

Google官方 详解 Android 性能优化【史诗巨著之内存篇】

尊重博主原创,如需转载,请附上本文链接http://blog.csdn.net/chivalrousman/article/details/51553114#t16 为什么关注性能 对于一款APP,用户首先关注的是 app的性能,而不是APP本身的属性功能,用户不关心你是否是搞社交,是否搞电商,是否是一款强大的美图滤镜app,用户首先关注的是 性能--性能不好,用户会直接卸载,在应用市场给一个恶狠狠得差评,小则影响产品口碑,大则影响公司的品牌和声誉,作为程序员,app的性能更应该作为我们关注的一