一、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();