再看heap 和stack,还有多了解内存

heap

1.堆石一个“运行时”数据区,类实例化的对象就是从堆上分配的空间。

2.在堆上分配的空间一般通过new 等 等指令来创建

3.Java针对指针操作和C++的区别就是,java不需要在空间不用的时候显示释放。

4.JAVA的堆是由垃圾回收机制来负责处理的 ,堆是动态分配内存大小的,GC可以自动回收不在使用的内存空间

5.因为是动态内存所以 存取速度慢。

 

stack

1.存放基础数据类型和对象句柄

2.存取速度比堆快

3.stack的数据可以共享 (Int a=5 int b=5 两个变量都是用在stack的值)

4.stack的数据必须是大小和生命周期确定,缺乏灵活性。

 

可以看看你有多少内存

最大内存

System.out.print("maxMemory:");
System.out.println(Runtime.getRuntime().maxMemory()/1024/1024+"M");

已使用内存

System.out.println(Runtime.getRuntime().totalMemory()/1024/1024+"M");

 

设置java启动内存大小

-Xms256m -Xmx512m

-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size

 

二维数组比一维数组占用更多内存空间

 

用 "arrayCopy()" 提高数组截取速度


即使程序员可以做的只有调用 "System.gc()" 来 " 建议 " 执行垃圾收集器程序,但也不能保证gc执行

 

" 新生代 " 区域设置参数是 "-Xmn" ,用这个参数可以制定 " 新生代 " 区域的大小。

### 三、Android内存泄漏中与堆栈相关的类型 在 Android 内存泄漏问题中,堆(Heap栈(Stack)是两个关键的内存区域,它们分别承担不同的内存管理职责,也对应着不同类型的内存泄漏问题。 #### 3.1 堆内存泄漏(Java Heap Leak) 堆内存Java 虚拟机(JVM)管理的主要内存区域,用于存放对象实例。堆内存泄漏通常表现为对象在不再被使用时仍被引用,导致垃圾回收器(GC)无法回收这些对象,进而造成内存持续增长,最终可能引发 `OutOfMemoryError` [^2]。 常见的堆内存泄漏类型包括: - **静态引用泄漏**:静态变量持有 `Activity` 或 `Context` 的引用,导致对象无法回收。 - **匿名内部类泄漏**:如 `Handler`、`AsyncTask` 等内部类持有外部类的引用。 - **未注销监听器**:如 `BroadcastReceiver`、`SensorEventListener` 等未在生命周期结束时注销。 - **长生命周期对象持有短生命周期引用**:如单例模式中错误地持有 `Activity` 上下文。 - **集合类未清理**:如 `List`、`Map` 中不断添加对象而不移除。 - **线程未终止**:如 `Thread` 或 `TimerTask` 持有外部类引用且未在销毁时终止。 这些泄漏类型均发生在堆内存中,通常可以通过工具如 LeakCanary 或 Android Profiler 进行检测分析 [^1]。 #### 3.2 栈内存泄漏(Stack Leak) 栈内存用于存储函数调用时的局部变量、方法参数、返回地址等,其生命周期与线程的执行密切相关。栈内存泄漏在 Android 中相对少见,但仍然存在一些典型场景: - **递归调用未终止**:无限递归可能导致栈溢出(`StackOverflowError`),虽然这更偏向于逻辑错误,但也属于一种栈内存管理不当。 - **本地方法栈泄漏**:使用 JNI 调用本地代码时,若未正确释放 `JNIEnv` 或 `jobject` 等资源,可能导致本地方法栈内存泄漏。 - **线程未正确退出**:线程中未释放局部变量或未退出循环,导致线程持续运行并占用栈空间。 与堆内存泄漏不同,栈内存泄漏往往表现为线程相关的资源未释放,而非对象引用未断开。 #### 3.3 堆与栈在内存分配中的区别 - **堆内存分配**:堆内存由 JVM 自动管理,对象的创建销毁由垃圾回收机制负责。开发者通过 `new` 创建对象,GC 负责回收不再被引用的对象。 - **栈内存分配**:栈内存由系统自动管理,每个线程拥有独立的栈空间。局部变量在方法调用期间分配,方法执行结束后自动释放。 在内存泄漏分析中,堆内存泄漏更常见且复杂,而栈内存泄漏通常与线程控制 JNI 调用相关。 #### 3.4 内存泄漏检测与分析方法 为了区分堆内存泄漏,开发者可以使用以下工具方法: - **Android Profiler**:实时监控堆内存使用情况,查看对象分配引用链。 - **LeakCanary**:自动检测 Java内存泄漏,并提供引用链分析。 - **MAT(Memory Analyzer)**:用于分析内存快照(hprof 文件),查找未释放的对象及其引用路径。 - **JNI 调试工具**:如 `jstack`、`jmap` 等,用于分析本地方法栈线程状态。 - **procrank 工具**:用于查看进程内存使用情况,包括 VSS、RSS、PSS 等指标 [^4]。 此外,还可以通过编写代码定时打印内存信息,观察非 Java 层的内存变化,以判断是否存在 Native 层泄漏 [^3]。 --- ```java // 示例:避免静态引用导致的堆内存泄漏 public class SafeActivity extends Activity { private static Context context; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = getApplicationContext(); // 使用 Application Context 避免泄漏 } } ``` --- ```java // 示例:使用弱引用避免 Handler 导致的内存泄漏 public class SafeHandlerActivity extends Activity { private Handler handler = new Handler(Looper.getMainLooper()) { public void handleMessage(Message msg) { // 处理消息 } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler.postDelayed(new Runnable() { @Override public void run() { // 延迟执行的操作 } }, 10000); } @Override protected void onDestroy() { handler.removeCallbacksAndMessages(null); // 清除所有消息回调 super.onDestroy(); } } ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值