一、java程序占用实际内存大小

1.1、java命令启动参数-Xms -Xmx的问题
        启动命令如下:java -server -Xms128m -Xmx128m -jar ****.jar
            java -X
            
       很多人错误的认为运行Java程序时使用-Xmx和-Xms参数指定的就是程序将会占用的内存,但是这实际上只是Java堆对象将会占用的内存。堆只是影响Java程序占用内存数量的一个因素。要更好的理解你的Java程序将会占用多大的内存需要先了解有哪些因素会影响到内存的占用。这些因素包括:

对象(Objects)
类(Classes)
线程(Theads)
本地数据结构(Native data structures)
本地代码(Native code)
        每个因素对内存占用的影响又会随着应用程序、运行环境和系统平台的不同而变化,那怎样计算总的内存占用量?是的,想得到一个准确的数字不是那么容易,因为你很难控制本地(Native)部分。你能控制的部分只有堆大小:-Xmx,类占用的内存:-XX:MaxPermSize,还有线程栈:-Xss控制每个线程占用的内存。注意当把栈大小设置的太小时会导致StackOverflow异常、程序出错。所以,计算公式为:

(-Xmx) + (-XX:MaxPermSize) + 线程数 * (-Xss) + 其它内存
2048

其它内存部分取决于本地代码占用的内存,如NIO、socket缓冲区、JNI等。它一般大约是jvm内存的5%左右。所以假设我们有下面的JVM参数和100个线程:

-Xmx1024m -XX:MaxPermSize=256m -Xss512k

那么jvm进程至少会占用内存数量为:1024m + 256m + 100*512k + (0.05 * 1330m) = 1396.5m

堆大小(MaxHeapSize):-Xmx; 类占用的内存:-XX:MaxPermSize;线程数 * 还有线程栈:-Xss控制每个线程占用的内存;其它内存--总内存的5% 
MaxHeapSize
# java -server -XX:+PrintCommandLineFlags
-XX:MaxHeapSize=4164074496
MaxPermSize
#
ThreadStackSize
#

jmap -heap pid

1.2、 堆(Heap)和非堆(Non-heap)内存
        按照官方的说法:“Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在Java虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heapmemory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。

1.3、 堆内存分配
        JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小。

1.4、非堆内存分配
J        VM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

1.5、JVM最大内存
        首先JVM内存限制于实际的最大物理内存(废话!呵呵),假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。

1.6、查看本机最大JVM大小
java -XshowSettings:vm

1.7、查看本机最大metaspace
java -XX:+PrintFlagsInitial | findstr MetaspaceSize

二、JVM参数配置
        我们学习Java GC机制的目的是为了实用,也就是为了在JVM出现问题时分析原因并解决之,JVM监控与调优主要的着眼点在于如何配置、如何监控、如何优化3点上。

在Java虚拟机的参数中,有3种表示方法

标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容;
非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容;
非Stable参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用(但是,这些参数往往是非常有用的);
本文只重点介绍一些重要和常用的参数,如果想了解全部参数,可以参考下面的文章:

JVM启动参数大全 zz - 岁月如哥 - BlogJava

三、标准参数
        其实标准参数是用过Java的人都最熟悉的,就是你在运行java命令时后面加上的参数,如java -version, java -jar等,输入命令java -help或java -?就能获得当前机器所有java的标准参数列表。

-client
        设置jvm使用client模式,这是一般在pc机器上使用的模式,启动很快,但性能和内存管理效率并不高;多用于桌面应用;

-server
        使用server模式,启动速度虽然慢(比client模式慢10%左右),但是性能和内存管理效率很高,适用于服务器,用于生成环境、开发环境或测试环境的服务端;

如果没有指定-server或-client,JVM启动的时候会自动检测当前主机是否为服务器,如果是就以server模式启动,64位的JVM只有server模式,所以无法使用-client参数;
        默认情况下,不同的启动模式,执行GC的方式有所区别:

启动模式

新生代GC方式

旧生代和持久代GC的方式

client

串行

串行

server

并行

并发

-classpath / -cp
        JVM加载和搜索文件的目录路径,多个路径用;分隔。注意,如果使用了-classpath,JVM就不会再搜索环境变量中定义的CLASSPATH路径。

四、JVM搜索路径的顺序为:

4.1、先搜索JVM自带的jar或zip包(Bootstratp搜索路径可以用System.getProperty("sun.boot.class.path")获得)

4.2、搜索JRE_HOME/lib/ext下的jar包(Extension搜索路径可以用System.getProperty("java.ext.dirs")获得)

4.3、搜索用户自定义目录,顺序为:当前目录(.),CLASSPATH,-cp(搜索路径System.getProperty("java.class.path")获得)

-verbose
        这是查询GC问题最常用的命令之一,具体参数如:

-verbose:class 输出jvm载入类的相关信息,当jvm报告说找不到类或者类冲突时可此进行诊断。

-verbose:gc 输出每次GC的相关情况。

-verbose:jni 输出native方法调用的相关情况,一般用于诊断jni调用错误信息。

五、非标准参数
        非标准参数,是在标准参数的基础上进行扩展的参数,输入“java -X”命令,能够获得当前JVM支持的所有非标准参数列表(你会发现,其实并不多哦)。

在不同类型的JVM中,采用的参数有所不同

-Xmn
        新生代内存大小,包括E区和两个S区的总和,使用方法如:-Xmn65535,-Xmn1024k,-Xmn512m,-Xmn1g (-Xms,-Xmx也是种写法)

-Xms
        初始堆的大小,也是堆大小的最小值,默认值是总共的物理内存/64(且小于1G),默认情况下,当堆中可用内存小于40%(这个值可以用-XX: MinHeapFreeRatio 调整,如-X:MinHeapFreeRatio=30)时,堆内存会开始增加,一直增加到-Xmx的大小;

-Xmx
        堆的最大值,默认值是总共的物理内存/64(且小于1G),如果Xms和Xmx都不设置,则两者大小会相同,默认情况下,当堆中可用内存大于70%(这个值可以用-XX: MaxHeapFreeRatio 调整,如-X:MaxHeapFreeRatio=60)时,堆内存会开始减少,一直减小到-Xms的大小;

整个堆的大小=年轻代大小+年老代大小,堆的大小不包含持久代大小,如果增大了年轻代,年老代相应就会减小,官方默认的配置为年老代大小/年轻代大小=2/1左右(使用-XX:NewRatio可以设置-XX:NewRatio=5,表示年老代/年轻代=5/1);

注:建议在开发测试环境可以用Xms和Xmx分别设置最小值最大值,但是在线上生产环境,Xms和Xmx设置的值必须一样,原因与年轻代一样——防止抖动;

-Xss
        这个参数用于设置每个线程的栈内存,默认1M

-Xprof
        跟踪正运行的程序,并将跟踪数据在标准输出;适合于开发环境调试。

-Xnoclassgc
        关闭针对class的gc功能;因为其阻止内存回收,所以可能会导致OutOfMemoryError错误,慎用;

-Xincgc
        开启增量gc(默认为关闭);这有助于减少长时间GC时应用程序出现的停顿;但由于可能和应用程序并发执行,所以会降低CPU对应用的处理能力。

-Xloggc:file
        与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。

若与verbose命令同时出现在命令行中,则以-Xloggc为准。

六、非Stable参数(非静态参数)
        以-XX表示的非Stable参数, JVM(Hotspot)中主要的参数可以大致分为3类

性能参数(Performance Options):用于JVM的性能调优和内存分配控制,如初始化内存大小的设置;

行为参数(Behavioral Options):用于改变JVM的基础行为,如GC的方式和算法的选择;

调试参数(Debugging Options):用于监控、打印、输出等jvm参数,用于显示jvm更加详细的信息;

对于非Stable参数,使用方法有4种:

-XX:+<option> 启用选项

-XX:-<option> 不启用选项

-XX:<option>=<number> 给选项设置一个数字类型值,可跟单位,例如 32k, 1024m, 2g

-XX:<option>=<string> 给选项设置一个字符串值,例如-XX:HeapDumpPath=./dump.core

七、性能参数
        性能参数往往用来定义内存分配的大小和比例,相比于行为参数和调试参数,一个比较明显的区别是性能参数后面往往跟的有数值,常用如下:

参数及其默认值

描述

-XX:NewSize=2.125m

新生代对象生成时占用内存的默认值

-XX:MaxNewSize=size

新生成对象能占用内存的最大值

-XX:MaxPermSize=64m

方法区所能占用的最大内存(非堆内存)

-XX:PermSize=64m

方法区分配的初始内存

-XX:MaxTenuringThreshold=15

对象在新生代存活区切换的次数(坚持过MinorGC的次数,每坚持过一次,该值就增加1),大于该值会进入老年代(年龄阈值)

-XX:MaxHeapFreeRatio=70

GC后java堆中空闲量占的最大比例,大于该值,则堆内存会减少

-XX:MinHeapFreeRatio=40

GC后java堆中空闲量占的最小比例,小于该值,则堆内存会增加

-XX:NewRatio=2

新生代内存容量与老生代内存容量的比例

-XX:ReservedCodeCacheSize= 32m

保留代码占用的内存容量

-XX:ThreadStackSize=512

设置线程栈大小,若为0则使用系统默认值

-XX:LargePageSizeInBytes=4m

设置用于Java堆的大页面尺寸

-XX:PretenureSizeThreshold= size

大于该值的对象直接晋升入老年代(这种对象少用为好)

-XX:SurvivorRatio=8

Eden区域Survivor区的容量比值,如默认值为8,代表Eden:Survivor1:Survivor2=8:1:1

八、行为参数
        行为参数主要用来选择使用什么样的垃圾收集器组合,以及控制运行过程中的GC策略等

参数及其默认值

描述

-XX:+UseSerialGC

启用串行GC,即采用Serial+Serial Old模式

-XX:+UseParallelGC

启用并行GC,即采用Parallel Scavenge+Serial Old收集器组合(-Server模式下的默认组合)

-XX:GCTimeRatio=99

设置用户执行时间占总时间的比例(默认值99,即1%的时间用于GC)

-XX:MaxGCPauseMillis=time

设置GC的最大停顿时间(这个参数只对Parallel Scavenge有效)

-XX:+UseParNewGC

使用ParNew+Serial Old收集器组合

-XX:ParallelGCThreads

设置执行内存回收的线程数,在+UseParNewGC的情况下使用

-XX:+UseParallelOldGC

使用Parallel Scavenge +Parallel Old组合收集器

-XX:+UseConcMarkSweepGC

使用ParNew+CMS+Serial Old组合并发收集,优先使用ParNew+CMS,当用户线程内存不足时,采用备用方案Serial Old收集。

-XX:-DisableExplicitGC

禁止调用System.gc();但jvm的gc仍然有效

-XX:+ScavengeBeforeFullGC

新生代GC优先于Full GC执行

九、调试参数
        调试参数,主要用于监控和打印GC的信息

参数及其默认值

描述

-XX:-CITime

打印消耗在JIT编译的时间

-XX:ErrorFile=./hs_err_pid<pid>.log

保存错误日志或者数据到文件中

-XX:-ExtendedDTraceProbes

开启solaris特有的dtrace探针

-XX:HeapDumpPath=./java_pid<pid>.hprof

指定导出堆信息时的路径或文件名

-XX:-HeapDumpOnOutOfMemoryError

当首次遭遇OOM时导出此时堆中相关信息

-XX:OnError="<cmd args>;<cmd args>"

出现致命ERROR之后运行自定义命令

-XX:OnOutOfMemoryError="<cmd args>;<cmd args>"

当首次遭遇OOM时执行自定义命令

-XX:-PrintClassHistogram

遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同

-XX:-PrintConcurrentLocks

遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同

-XX:-PrintCommandLineFlags

打印在命令行中出现过的标记

-XX:-PrintCompilation

当一个方法被编译时打印相关信息

-XX:-PrintGC

每次GC时打印相关信息

-XX:-PrintGC Details

每次GC时打印详细信息

-XX:-PrintGCTimeStamps

打印每次GC的时间戳

-XX:-TraceClassLoading

跟踪类的加载信息

-XX:-TraceClassLoadingPreorder

跟踪被引用到的所有类的加载信息

-XX:-TraceClassResolution

跟踪常量池

-XX:-TraceClassUnloading

跟踪类的卸载信息

-XX:-TraceLoaderConstraints

跟踪类加载器约束的相关信息

java程序占用实际内存大小相关推荐

  1. 通过显示当前 python 程序占用的内存大小来比较生成器和迭代器(转载)

    # 显示当前 python 程序占用的内存大小 import osimport psutil as psutildef show_memory_info(hint):# 获取当前进程的进程号pid = ...

  2. 怎么测试一个java程序占用的内存和cpu消耗?

    1.测试查看单独的class的资源消耗方法. Runtime r = Runtime.getRuntime();     long freeMemory = r.freeMemory(); long ...

  3. 通过keil编译明白自己的程序占用的内存大小。堆栈大小分配,32单片机片内存储flash的使用。

    目录 1.通过keil编译程序,得到自己代码需要单片机的flash和RAM大小 2.在程序中调整堆栈的大小 3.单片机片内flash的使用 1.通过keil编译程序,得到自己代码需要单片机的flash ...

  4. Java占Linux超过xms,linux下分析java程序占用CPU、内存过高

    一.CPU过高分析 1)使用TOP命令查看CPU.内存使用状态可以发现CPU占用主要分为两部分,一部分为系统内核空间占用CPU百分比,一部分为用户空间占用CPU百分比.其中CPU状态中标示id的为空闲 ...

  5. java应用程序占用高内存_对Java应用程序中的内存问题进行故障排除

    java应用程序占用高内存 重要要点 解决内存问题可能很棘手,但是正确的方法和正确的工具集可以大大简化此过程. Java HotSpot JVM可以报告几种OutOfMemoryError消息,因此务 ...

  6. java内存漏洞_处理Java程序中的内存漏洞

    Java 程序中也有内存漏洞?当然有.与流行的观念相反,在 Java 编程中,内存治理仍然是需要考虑的问题.在本文中,您将了解到什么会导致内存漏洞以及何时应该关注这些漏洞.您还有机会实践一下在您自己的 ...

  7. 你的java程序有没有内存泄露,java进程在linux系统中rss计算方式是什么样的?

    java进程在linux系统中rss计算方式如下: RSS = Heap size + MetaSpace + OffHeap size 其中OffHeap由线程堆栈,直接缓冲区,映射文件(库和jar ...

  8. java 进程占用系统内存过高分析

    JVM的内存 先放一张JVM的内存划分图,总体上可以分为堆和非堆(粗略划分,基于java8) 那么一个Java进程最大占用的物理内存为: Max Memory = eden + survivor + ...

  9. android获取当前应用占用的内存大小,Android分析已安装应用占用内存

    问题 Android开发时可以通过AndroidStudio提供的一些系列工具查看应用的内存占用,十分的方便. 但是如果是对一个成品的已安装App快速查看内存占用呢,下面简单讲两种方式. 方案一:to ...

最新文章

  1. Centos 内存占满 释放内存
  2. 腾讯优图开源首个医疗AI ML预训练模型
  3. python3 识别图片文字
  4. clang 搭建和编译boost 和zero ICE库 (Ubuntu10 64)
  5. 学长毕业日记 :本科毕业论文写成博士论文的神操作
  6. 【Libevent】Libevent学习笔记(二):创建event_base
  7. android dip转px
  8. [原创].如何解决Nios II SBTE中出现的undefined reference to `xxx'警告
  9. cocos2d-x学习知识点记录
  10. mysql-存储过程 使用游标获取数据集并且操作
  11. android studio module build,踩坑将一个AndroidStudio项目变成一个module引入到自己的项目中...
  12. Thingworx入门学习
  13. 四种软件开发模式(瀑布、迭代、螺旋、敏捷),对比分析
  14. 域名转移应该怎么做?域名转入是什么意思?手把手教你将阿里云备案域名转入到腾讯云
  15. FLASK开启调试模式,使程序修改即时生效
  16. Java狐仙ol,狐仙八大职业介绍 简要分为四类
  17. 淘宝买二级c语言题库可以嘛,大学计算机二级考试(C语言)试题在哪可以买?...
  18. [NCTF2019]SQLi 1regexp注入
  19. 微信公众号采集小爬虫
  20. 耐看娱乐更新招股书:前4个月营收降40% 阿里影业是股东

热门文章

  1. 41页数字政府整体规划方案 —数化万物赋能
  2. 【K3S 一】部署K3S集群(单Master)
  3. 解决Eclipse项目没错误但有红叉问题
  4. 微信小程序项目《天使童装》
  5. MySQL对大于小于等于符号的处理
  6. Sql Server 强制大小写区分方法
  7. 中心信令服务器编码,信令网的信令点编码
  8. 粗糙集 遗传matlab,一种基于遗传算法和粗糙集的属性约简方法及精神状态评估方法...
  9. AnyChat音视频互动开发平台(SDK)
  10. [含论文+开题报告+源码等]ssm+mysql实现零食商城系统(电商购物)