内存模型初识
虚拟机栈:stack Frame栈桢
程序计数器:(program Counter,PC)
本地方法栈:主要用于处理本地方法
堆(Heap):JVM最大的一块内存空间,与堆相关的是垃圾收集器.现代几乎所有的垃圾收集器都是分代收集算法,所以堆空间也基于此进行划分:新生代与老年代.Eden,From survivor,To suivivor.
方法区(Method Area):存储元信息.永久代(Permanent Generation),从JDK1.8废弃,使用元空间(meta space)
直接内存:(Direct Memory)
new关键字创建对象的三个步骤:
1.在堆内存中创建出对象实例
2.为对象的实例成员变量赋初值
3.将对象的引用返回
-Xms5m -Xmx5m -XX:+HeapDumpOnOutOfMemoryError
//堆内存溢出
public class MyTest1 {
public static void main(String[] args) {
List<MyTest1> list = new ArrayList<>();
for (;;){
list.add(new MyTest1());
//System.gc();
}
}
}
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid1045.hprof ...
Heap dump file created [9059207 bytes in 0.141 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.cy.jvm.memory.MyTest1.main(MyTest1.java:13)
//虚拟机栈溢出. -Xss160k 160k为推荐栈的最小内存
public class MyTest2 {
private int length;
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public void test() {
this.length++;
test();
}
public static void main(String[] args) {
MyTest2 myTest2 = new MyTest2();
try {
myTest2.test();
} catch (Throwable e) {
System.out.println(myTest2.length);
e.printStackTrace();
}
}
}
772
java.lang.StackOverflowError
at com.cy.jvm.memory.MyTest2.test(MyTest2.java:17)
at com.cy.jvm.memory.MyTest2.test(MyTest2.java:18)
at com.cy.jvm.memory.MyTest2.test(MyTest2.java:18)
at com.cy.jvm.memory.MyTest2.test(MyTest2.java:18)
at com.cy.jvm.memory.MyTest2.test(MyTest2.java:18)
at com.cy.jvm.memory.MyTest2.test(MyTest2.java:18)
at com.cy.jvm.memory.MyTest2.test(MyTest2.java:18)
at com.cy.jvm.memory.MyTest2.test(MyTest2.java:18)
at com.cy.jvm.memory.MyTest2.test(MyTest2.java:18)
.....
//死锁
public class MyTest3 {
public static void main(String[] args) {
new Thread(() -> A.method(), "Thread-A").start();
new Thread(() -> B.method(), "Thread-B").start();
}
}
class A {
public static synchronized void method() {
System.out.println("method A");
try {
Thread.sleep(5000);
B.method();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class B {
public static synchronized void method() {
System.out.println("method B");
try {
Thread.sleep(5000);
A.method();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
method A
method B
-XX:MaxMetaspaceSize=200m
/**
* 方法区内存溢出错误
*/
public class MyTest4 {
public static void main(String[] args) {
for (; ; ) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyTest4.class);
enhancer.setUseCache(false);
enhancer.setCallback(((MethodInterceptor) (obj, method, args1, proxy) -> proxy.invokeSuper(obj, args1)));
System.out.println("hello world");
enhancer.create();
}
}
}
.....
hello world
hello world
hello world
Exception in thread "main"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"