Java内存模型以及内存溢出

一、java内存模型

程序计数器:

线程独有,非native方法,保存了当前需要执行的指令的地址,native方法,是undefined.
保证每个线程的切换时恢复之前的执行位置,需要线程独有一个程序计数器,保存线程的指令地址。

java栈或者虚拟机栈:

每个线程都有一个自己的java栈,存放的是栈帧,一个栈帧包含:局部变量表(局部变量,形参),操作数栈,指向运行时常量的引用,方法返回地址(调用它的地方)。方法的调用是入栈和出栈的操作。

本地方法栈:

和java栈一样,但是native方法的表示。

堆:

线程共享,一个jvm有一个

方法区:

线程共享,存储的有类信息,静态变量,常量,代码。

二、内存溢出。

StackOverflowError:

栈深度超过线程栈大小,或者栈帧占用空间过大。一般循环调用或者递归调用会出现。

创建过多线程时出现的OOM:

降低线程数量。可快设置jvm参数,降低每个线程的栈空间大小

1、Rxjava,io线程池中线程会一直增加

 RxCachedThreadScheduler-169(632)
java.lang.OutOfMemoryError
pthread_create (1040KB stack) failed: Out of memory
1 hy.sohu.com.app.chat.model.ChatPollManager.getData(ChatPollManager.java:122)

2、Mqtt重新连接时,恢复数据时报的错误,不知道恢复的是什么数据,可能是目录内文件过多,过大造成。

java.lang.OutOfMemoryError
EnsureLocalCapacity
解析原始
1 java.io.UnixFileSystem.list0(Native Method)
2 java.io.UnixFileSystem.list(UnixFileSystem.java:303)
3 java.io.File.list(File.java:1122)
4 java.io.File.listFiles(File.java:1286)

解决方案:
查找缓存内容,是否可避免缓存
侵入式编程,判断大小后再决定是否遍历。

三、获取内存信息

Heap Size:总共的内存大小
Heap Alloc:分配的内存大小
Heap Free:剩余的内存大小
Pss Total:实际使用内存,包含了独占内存页的值加上跨进程的共享页按照共享比例计算的值。
Private Dirty:进程独占内存页的值,即进程独占的,不能被换页共享的内存。

 long max = Runtime.getRuntime().maxMemory()/1024;
        long total = Runtime.getRuntime().totalMemory()/1024;
        long free = Runtime.getRuntime().freeMemory()/1024;
        long alloc = (total - free);

        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        Debug.MemoryInfo[] memoryInfo = activityManager.getProcessMemoryInfo(new int[]{Process.myPid()});
        long pssTotal = memoryInfo[0].getTotalPss();
        long privateDirty = memoryInfo[0].getTotalPrivateDirty();

猜你喜欢

转载自blog.csdn.net/weixin_34067102/article/details/87357898