一、本地(Native)方法
一个本地方法就是一个 Java 调用非 Java 代码的接口,一个本地方法的实现由非Java 语言实现,比如 C 语言。这个特征并非 Java 特有,很多编程语言都有这一机制。
在定义一个本地方法时,并不提供实现体(有些想定义一个接口),因为其实体是由非 java 语言在外面实现
本地接口的作用是融合不同的编程语言为 Java 所用,它的初衷是融合 C/C++ 程序。
使用本地方法的目的
1.与环境交互
2.与操作系统交互
3.Sun‘Java
二、逃逸分析与标量替换
逃逸分析:是JVM为了优化对象分配而做的一种优化措施。发生在第一步判断对象是否可以在栈上分配的时候,JVM通过逃逸分析确定该对象不会被外部访问。如果不会逃逸可以将该对象在栈上分配内存,这样该对象所占用的内存空间就可以随栈帧出栈而销毁,节约堆内存,减轻GC的压力。
标量替换:通过逃逸分析确定该对象不会被外部访问,并且对象可以被进一步分解时,JVM不会创建该对象,而是将该对象成员变量分解若干个被这个方法使用的成员变量所代替,这些代替的成员变量在栈帧或寄存器上分配空间,这样就不会因为没有一大块连续空间导致对象内存不够分配。
三、CAS
在解决对象创建时提到了有两种可选方案:其中一种是对分配内存空间的动作进行同步处理,采用CAS配上失败重试的方式保证更新操作的原子性;(另外一种采用本地线程分配缓冲区)
CAS算法是硬件对于并发操作的支持,其中包含了三个操作数:内存值V,预估值A和更新值B。没当要执行更新操作时,会先在同步方法中比较内存值和预估值是否相等,如果相等才会用更新值替换内存值,否则什么也不做。
四、堆转储快照
堆转储是Java内存的快照, 它包含有关快照触发时堆中Java对象和类的信息,是一个 诊断任何与Java内存相关的问题都是至关重要的工件。获取堆转储的几个方法:
1.识别流程编号
2.jmap工具捕获堆转储
3.通过传递'-XX:+ HeapDumpOnOutOfMemoryError'系统属性来在JVM遇到OutOfMemoryError时捕获堆转储。
五、内存泄漏与内存溢出
内存溢出:(out of memory)通俗理解就是内存不够,比如创建对象时,对象的总内存超出了堆内存,就叫内存溢出。
内存泄漏:(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果
六、JAR文件
JAR文件是一种软件包文件格式,通常用于聚合大量的Java类文件、相关的元数据和资源文件到一个文件,以便开发Java程序。
JAR文件是一种归档文件,以ZIP格式构建,以.jar为文件扩展名。用户可以使用JDK自带的jar命令创建或提取JAR文件。也可以使用其他zip压缩工具,不过压缩时zip文件头里的条目顺序很重要,因为Manifest文件常需放在首位。JAR文件内的文件名是Unicode文本。
一些参数设置
1.-Xmx、-Xms、-Xss
-Xms:是指设定程序启动时占用内存大小。
-Xmx:是指设定程序运行期间最大可占用的内存大小。(将-Xms与-Xmx值设置一样可以避免堆内存自动扩展)
2.-XX:+/-UseTLAB与-XX:+TLABSize
TLAB:本地线程分配缓冲区
-XX:+UseTLAB设置是否使用TLAB
-XX:+TLABSize 设置TLAB大小
3.-XX:FieldsAllocationStyle
对象中,实例数据部分的存储顺序会受到虚拟机分配策略参数,即-XX:FieldsAllocationStyle参数的影响
类型0, 引用在原始类型前面, 然后依次是longs/doubles, ints, shorts/chars, bytes, 最后是填充字段, 以满足对其要求.
类型1, 引用在原始类型后面
类型2, JVM在布局时会尽量使父类对象和子对象挨在一起。
4.+XX:CompactFields
对象实例子数据存储时,相同宽度的字段总是被分配到一起存储 ,在满足这个前提条件的情况下,在父类中定义的变量会出现在子类之前。
但是如果将+XX:CompactFields参数值为true(默认就为true),那子类之中较窄的变量也允许插入父类变量的空隙之中,以节省出一点点空间。
5.-XX:+HeapDumpOnOutOf-MemoryError
JVM发生OOM时,-XX:+HeapDumpOnOutOfMemoryError参数表示自动生成DUMP文件。也可以指定文件名称,例如:-XX:HeapDumpPath=${目录}/java_heapdump.hprof。如果不指定文件名,默认为:java<pid><date><time>heapDump.hprof。
6.-Xoss与-Xss
-Xoss参数:设置本地方法栈大小,虽然存在,但实际上是没有任何效果的。
-Xss:设置栈最小容量。参数-Xss128k可以正常用于32位Windows系统下的JDK 6,但是如果用于64位Windows系统下的JDK 11,则会提示栈容量最小不能低于180K,而在Linux下这个值则可能是228K,如果低于这个最小限制,HotSpot虚拟器启动时会给出如下提示
The Java thread stack size specified is too small. Specify at least 228k
7.-XX:PermSize和-XX:MaxPermSize
-XX:PermSize和-XX:MaxPermSize用来限制永久代参数大小
8.-XX:MaxMeta-spaceSize与-XX:MaxPermSize
两个参数都是限制方法区容量(最大),MaxMeta-spaceSize在JDK8以上版本使用,-XX:MaxPermSize在JDK7版本使用
9.-XX:MaxMetaspaceSize与-XX:MetaspaceSize
-XX:MaxMetaspaceSize:设置元空间最大值,默认是-1,即不限制,或者说只受限于本地内存大小。
XX:MetaspaceSize:指定元空间的初始空间大小,以字节为单位
-XX:MinMetaspaceFreeRatio:作用是在垃圾收集之后控制最小的元空间剩余容量的百分比,可减少因为元空间不足导致的垃圾收集的频率。
-XX:Max-MetaspaceFreeRatio,用于控制最大的元空间剩余容量的百分比。
10.-XX:MaxDirectMemorySize
通过-XX:MaxDirectMemorySize参数指定直接内存(Direct Memory)的容量大小。
11.Xnoclassgc参数
HotSpot虚拟机提供了Xnoclassgc参数进行控制方法区堆类型的回收,还可以使用-verbose:class以及-XX:+TraceClass-Loading、-XX: +TraceClassUnLoading查看类加载和卸载信息,其中-verbose:class和-XX:+TraceClassLoading可以在 Product版的虚拟机中使用,-XX:+TraceClassUnLoading参数需要FastDebug版的虚拟机支持。
12.-XX:+UseCondCardMark
-XX:+UseCondCardMark参数用来决定是否开启卡表更新的条件判断。开启会增加一次额外判断的开销,但能够避免伪共享问题。
13.-XX:SurvivorRatio、-XX: PretenureSizeThreshold
-XX:SurvivorRatio:定义了新生代中Eden区域和Survivor区域(的比例,默认为8,也就是说Eden占新生代的8/10。
-XX:PretenureSizeThreshold参数:设置一个判断阈值,当大对象的值大于阈值值的对象直接在老年代分配。这样做的目的就是避免在Eden区及两个Survivor区 之间来回复制,产生大量的内存复制操作。
14:-XX:+/-UseParNewGC
-XX:+UseConcMarkSweepGC:设定ParNew收集器是激活CMS后的默认新生代收集器,也可以使用-XX:+/-UseParNewGC选项来强制指定或者禁用它。JDK9以后取消了这个参数,意味着ParNew和CMS收集器只能相互配合使用,而不能和其他垃圾收集器配合使用。
15.-XX:ParallelGCThreads
-XX:ParallelGCThreads:表示JVM在进行并行GC的时候,用于GC的线程数。
16.-XX:MaxGCPauseMillis与-XX:GCTimeRatio参数-XX:+UseAdaptiveSizePolicy
-XX:MaxGCPauseMillis:Parallel Scavenge收集器收集器控制最大垃圾收集停顿时间的参数。
-XX:GCTimeRatio:直接设置吞吐量大小。
-XX:+UseAdaptiveSizePolicy:打开虚拟机动态调整停顿时间或者吞吐量参数的参数。
17.-XX:CMSInitiatingOccu-pancyFraction
-XX:CMSInitiatingOccu-pancyFraction:调整CMS的触发百分比,适当调高后可以降低内存回收频率,获取更好的性能。
18.-Xlog
-Xlog参数包含了HotSpot所有功能的日志。(通过命令行使用)
19.-XX: MaxTenuringThreshold
-XX: MaxTenuringThreshold:对象晋升老年代的年龄阈值。
20.-XX: +TraceClassLoading
-XX: +TraceClassLoading:此参数用于动态跟踪类的加载,此操作是会导致子类加载的。
使用方法(通过命令行使用):先写一个java类,比如Test.java;然后先用javac Test.java进行编译,再用java -XX:+TraceClassLoading Test得到加载日志
21.-Client参数与-Server参数
使用“-client”强制指定虚拟机运行在客户端模式。
或“-server”参数去强制指定虚拟机运行在服务端模式。
22.-Xint与-Xcomp
-Xint:”强制虚拟机运行于“解释模式(解释器)
-Xcomp:”强制虚拟机运行于“编译模式(编译器 )
23.-XX:UseCounterDecay与-XX:CounterHalfLifeTime
再判断热点代码时,方法调用计数器统计的是方法被调用的相对的执行频率,即一段时间之内方法被调用的次数。如果方法的调用次数仍然不足以让它提交给即时编译器编译,那该方法的调用计数器就会被减少一半,这个过程被称为方法调用计数器热度的衰减(Counter Decay),而这段时间就称为此方法统计的半衰周期。
-XX:UseCounterDecay:关闭热度衰减,让方法计数器统计方法调用的绝对次数。
-XX:CounterHalfLifeTime:设置半衰周期的时间,单位是秒。
24.-XX:+PrintCompilation
-XX:+PrintCompilation:要求虚拟机在即时编译时将被编译成本地代码的方法名称打印出来,通过此参数可以查看某个方法是否被编译过。