JVM调优


判定是否需要加机器要结合top命令中的load average和cpu使用率率来看,不是很高时就要考虑内部程序优化参见

查看机器内存:cat /proc/meminfo |grep MemTotal|awk '{print int($2/1048756+0.5)}'
查看cpu核数:grep ‘model name’ /proc/cpuinfo | wc -l
统计连接数:
netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’
查看某个进程下的线程数:cat /proc/进程号/status
查看某个进程下所有线程的情况:ps p 4941 -L -o pcpu,pid,tid,time,tname,cmd 或者(top -Hp pid)
这里看到的线程id需要转换成16进制才能配合jstack使用,16进制查询 printf “%x\n” 3046,再利用得到的字符串用jstack 21711 | grep 54ee 查询对应的线程信息

查看Linux系统限制:ulimit -a
将文件从docker里面复制到容器外面:sudo docker cp d96b8c6f3f03:/opt/taobao/java/bin/tem.dump /opt/
远程复制:scp local_file remote_username@remote_ip:remote_folder

export MEM_TOTAL="$(cat /proc/meminfo |grep MemTotal|awk '{print int($2/1048756+0.5)}')"
(( JVM_Xms=$MEM_TOTAL / 2 )) //初始化的堆内存
(( JVM_Xmx=$MEM_TOTAL / 2 )) //最大的堆内存
(( JVM_XXMaxDirectMemorySize=$MEM_TOTAL / 4 )) //本地直接内存大小

JPS:查看虚拟机进程ID和启动参数
jps -lv显示进程ID(不一定是PID),主类,启动参数

jstat:主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。
利用jps查询出来的ID查看GC线程的信息 每隔250毫秒打印一次 共打印3次 jstat -gc 37 250 3

JVM调优_第1张图片
结果分析参见

jinfo:动态查看jvm的配置参数信息
jinfo -flags process_id :查看jvm的参数
jinfo -sysprops process_id : 查看java系统参数

jstack:打印堆栈信息
- F :强制输出
- l :现实锁信息

查看Linux服务器负载

线程上下文切换:

如果是优先级相同的线程,CPU会给每个线程分配一个时间片,过了这个时间段就会将这个线程的快照保存起来并将这个线程挂起,进而执行下一个线程。

为什么将堆栈分开呢?

  • 从软件设计角度,栈代表了处理逻辑指令,跳转…,堆代表了数据
  • 分离开,可以使多个栈共享一块堆内存,节省空间
  • 栈只能向上增长一般分配好不会就增长了,而堆可以动态增长
  • 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢

为什么基本类型不放在堆中存储呢?

基本类型一般占用1-8个字节,需要的空间比较小,而且应为是基本类型长度不会动态增长(长度固定),因此栈中存储就够了

栈的大小通过-xss 设置,默认1M,一般70万行代码约占用117k大小

引用类型:

  • 强引用(造成内存溢出的引用):一般通过new生成的
  • 软引用:gc时jvm会根据剩余内存的多少决定是否回收软引用,做缓存
  • 弱引用:下一次gc一定会被回收,生命周期只存在于一个gc回收周期
  • 虚引用:幽灵引用

你可能感兴趣的:(JVM)