第一、概念:
1、方法区:存放已经加载的类信息、常量、静态变量以及方法代码的内存区域。
2、常量池:常量池是方法区的一部分,存放常量、类中的符号引用。
3、堆区:由程序员控制,存放类的对象实例。
4、栈区:由操作系统控制,存放方法运行时产生的局部变量、方法出口等信息。
5、java类的完整的生命周期
满足下面三种情况的全部,类将被卸载
a,该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。
b,加载该类的ClassLoader已经被回收。
c,该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。
第二,Android的java程序为什么容易出现OOM
这是因为android系统对dalvik的vm heapsize做了硬性限制,当java进程申请的内存空间超出阀值的时候,就会出现OOM异常。这样设计的目的是让更多的进程同时进驻内存,等程序再次运行时,不需要重新创建进程以及加载到内存了,加快了响应时间,这样迫使每个app使用较小的内存。
那么如果对于需要更多内存空间的大型app,如何跳出这个heapsize限制呢?
1、创建子进程,这样就可以把一些新的对象分配到子进程的heap上了,创建子进程会增加系统开销,所以要视情况而定。
创建子进程的方法:在AndroidManifest.xml的<Application>以及子标签的属性中配置android:process="子进程的包名"。
2、使用jni在native heap上申请空间(推荐使用)
JNIEXPORT void JNICALLJava_com_example_demo_TestMemory_nativeMalloc(JNIEnv *, jobject)
{
void * p= malloc(1024*1024*50);
SLOGD("allocate50M Bytes memory");
if (p !=NULL)
{
//memorywill not used without calling memset()
memset(p,0, 1024*1024*50);
}
else
SLOGE("mallocfailure.");
….
….
free(p); //free memory
}
3、使用显存(操作系统预留RAM的一部分作为显存)