jvm内存-spark

 

 

java虚拟机是一种能够运行java字节码的虚拟机。作为一种编程语言的虚拟机,实际上不只是专门用于java语言,只要
生成的编译文件匹配jvm对加载编译文件格式要求,任何语言都可以由jvm编译运行。
类装载子系统、运行时数据区(堆,栈等)、执行引擎.

运行时数据区:堆、栈(线程)、本地方法栈、方法区(元空间,jdk1.8之后是不在虚拟机中,以系统内存为主)、程序计数器。
栈(线程):栈帧(局部变量表、操作数栈、动态链接、方法出口)、main栈帧主线程(局部变量表)    --main执行完,线程销毁,里面的东西都要被销毁
堆:年轻代(伊甸园、from,to)、老年代
程序计数器:标示下一个jvm指令的内存区,每个线程又有自己单独的程序计数器
元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小

一个方法对应一个栈帧区域.
操作数栈:临时的中转操作内存,进行指令逻辑,一个指令压栈出栈,下一个指令继续
方法出口:返回到main线程中.
栈里面有指针指向堆中的对象.
方法区(jdk1.8之后不是虚拟机的组成了,是操作系统的内存,只是可以划分):常量、静态变量、类元信息(类的描述信息)
堆中对象有指针指向方法区中类元信息指针
对象信息:对象头信息(锁信息、)
动态连接:运行期间用符号转化为直接引用(指向数据所存地址的指针或句柄),下次就不用再解析了  表示一个方法的所有指令码(就是方法名)
本地方法栈:执行引擎调用其他语言写的(eg:c)方法。native。

虚拟机调优就是“堆”,占的内存很大。默认老年代占堆三分之二,年轻代占三分之一。而年轻代中,
伊甸园区(new对象)占年轻代的五分之四,survior区占五分之一(里面有from区、to区)。一旦伊甸园区满了,执行引擎开启垃圾收集线程。年轻代有的经过几次gc都没有销毁的就会被挪用到老年代。   

轻gc不会停用户线程(年轻代满了),from区到to区,默认转15次就到老年区

老年代内存大,gc一次时间长

gcRoots根节点:类加载器、Thred、虚拟机栈的本地变量表、static成员、常量引用、本地方法栈的变量等等

某个区放满就会引起gc,向下个区放或者释放,直到老年区 称为Major GC,当整个堆满了(会产生full gc,所以线程都停掉,就是业务系统停掉了,执行full gc)。
年轻代的gc,称为minor gc。其他的情况也可能会产生full gc,不定时,比如各个区空间小了,内存泄露了。concurrent-mode-failure:当cms gc正进行时,
此时有新的对象要进行old代,但是old代空间不足造成的

对于使用RMI来进行RPC或管理的Sun JDK应用而言,默认情况下会一小时执行一次Full GC

虚拟机调优就是调整full gc执行的次数,减少执行时间.电商大促销,严重full gc导致系统直接卡死。

可以打印gc日志,命令jstat -gc 2344

full gc回收年轻代,也回收老年代。如果老年代的对象都是引用的,这样gc也搞不定,程序自己的bug。
程序启动慢,相当的可能是不停的执行full gc操作

jdk1.8之后,元空间(动态扩展,最大的是系统排除运行时内存的剩余内存),默认21m,达到21m就会full gc回收,回收之后变0左右,就会把默认值调小。如果回收后没有
太大的变化,就会调大。

1、 System.gc()方法的调用
2、老年代空间不足
3、永生区(元空间)空间不足
4、CMS GC日志出现promotion failed和concurrent mode failure

分析GC结果,确定是否需要调优,可参考以下标准(实际标准以应用的实际情况为准)

    Minor GC平均耗时少于50毫秒
    Minor GC平均频率少于10秒
    Full GC平均耗时少于1秒
    Full GC平均频率少于10分钟

当出现OutOfMemoryError时,要确定是什么问题,是内存分配不足还是因为内存泄漏或者没有及时,可以通过jmap命令或者在命令行加入-XX:+HeapDumpOnOutOfMemoryError,然后对dump出的Heap进行分析(可以使用MAT或者jvisualvm工具)

静态连接就是java加载类

能调整的就是元空间和堆

2014-07-18T16:02:17.606+0800(当前时间戳): 611.633(时间戳): [GC(表示Young GC) 611.633: [DefNew(单线程Serial年轻代GC): 843458K(年轻代垃圾回收前的大小)->2K(年轻代回收后的大小)(948864K(年轻代总大小)), 0.0059180 secs(本次回收的时间)] 2186589K(整个堆回收前的大小)->1343132K(
整个堆回收后的大小)(3057292K(堆总大小)), 0.0059490 secs(回收时间)] [Times: user=0.00(用户耗时) sys=0.00(系统耗时), real=0.00 secs(实际耗时)]

命令:
jinfo -flags 2344  查看当前项目jvm参数
jmap -dump:format=b,file=temp.hprof 2344  //导出dump文件(不过会暂停应用,导出内存快照)
jstack 2344   查看当前项目线程情况

grep `printf "%x\n" 7992` test -A 30     7992这个线程

grep `printf "%x\n" 938` test -A 30


得到进程ID为21711,第二步找出该进程内最耗费CPU的线程,可以使用
1)ps -Lfp pid
2)ps -mp 7957 -o THREAD,tid
3)top -Hp pid

printf "%x\n" 21742  得到21742十六进制

jstack 2344 | grep 981

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值