JVM基础篇-本地方法栈与堆
本地方法栈
- 什么是本地方法?
本地方法即那些不是由java层面实现的方法,而是由c/c++实现交给java层面进行调用,这些方法在java中使用native
关键字标识
public native int hashCode()
- 本地方法栈的作用?
为本地方法提供内存空间
堆
什么是堆?
- Heap 堆,通过 new 关键字,创建对象都会使用堆内存
特点
- 它是线程共享的,堆中对象都需要考虑线程安全的问题
- 有垃圾回收机制
堆内存溢出
造成堆内存溢出的原因
- 对象一直被引用无法被垃圾回收器回收,随着对象越来越多导致堆内存溢出
示例代码
package com.vmware.stack;
import java.util.ArrayList;
import java.util.List;
/**
* @apiNote 演示堆内存溢出 java.lang.OutOfMemoryError
* -Xmx8m 配置堆内存大小
*/
public class Demo5 {
public static void main(String[] args) {
int i = 0;
try {
List<String> list = new ArrayList<>();
String a = "hello";
while (true) {
list.add(a);
a = a + a;
i++;
}
} catch (Throwable e) {
e.printStackTrace();
System.out.println(i);//18
}
}
}
java.lang.OutOfMemoryError: Java heap space
at java.base/jdk.internal.misc.Unsafe.allocateUninitializedArray0(Unsafe.java:1382)
at java.base/jdk.internal.misc.Unsafe.allocateUninitializedArray(Unsafe.java:1375)
at java.base/java.lang.StringConcatHelper.newArray(StringConcatHelper.java:497)
at java.base/java.lang.StringConcatHelper.simpleConcat(StringConcatHelper.java:421)
at java.base/java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(DirectMethodHandle$Holder)
at java.base/java.lang.invoke.DelegatingMethodHandle$Holder.reinvoke_L(DelegatingMethodHandle$Holder)
at java.base/java.lang.invoke.Invokers$Holder.linkToTargetMethod(Invokers$Holder)
at com.vmware.stack.Demo5.main(Demo5.java:19)
设置堆内存大小
- -Xmx
堆内存诊断
-
jps 工具:查看当前系统中有哪些 java 进程
-
jmap 工具:查看堆内存占用情况 jmap - heap 进程id
package com.vmware.stack; public class Demo6 { public static void main(String[] args) throws InterruptedException { System.out.println("1..."); Thread.sleep(30000); byte[] array = new byte[1024 * 1024 * 10]; System.out.println("2..."); Thread.sleep(30000); array = null; System.gc(); System.out.println("3..."); Thread.sleep(1000000L); } }
-
jconsole 工具:图形界面的,多功能的监测工具,可以连续监测
案例
垃圾回收后,内存占用仍然很高
可以使用可视化工具jvisualvm进行堆dump,进行内存分析