在Android中,公共类中的全局变量或在线程中声明它有什么好处?
我从
一个非常好的 Thread实现线程,在这里,String updateWords
每次触发线程时都会声明。
那么,这会影响内存吗?
我宣布不。变量,所以,我问。
任何帮助将不胜感激。谢谢你。
在Android中,公共类中的全局变量或在线程中声明它有什么好处?
我从
一个非常好的 Thread实现线程,在这里,String updateWords
每次触发线程时都会声明。
那么,这会影响内存吗?
我宣布不。变量,所以,我问。
任何帮助将不胜感激。谢谢你。
You should only use global variables when the alternative is far, far worse.
Starting a Thread is 1000x more expensive than creating a reference to a String. If you are concerned about the usage of a single String, or even a small number, you shouldn't be creating a Thread at all.
Even if you have a few thousand Strings they will use the same amount of memory as global variables as they do local variables. The only differences is the global variables use heap and the local variables use the stack and heap with most of the usage still on the heap.
Java(和其他语言)中有几个内存区域用于各种任务。
最昂贵的是堆内存,基本上使用new
关键字创建的所有内容都进入堆。
然后是堆栈,可以说是一个本地“堆”,但没有与创建堆变量相关的大部分成本,因此速度更快。几乎所有的局部变量updateWords
都位于堆栈中。
寄存器是快如闪电的处理器内部变量。JVM 优化器总是会在合适的时候尝试将内容放入内部寄存器,但由于寄存器的数量非常有限,因此只有非常常用的变量才会放在那里。
但昂贵意味着堆和寄存器之间的执行时间差为 0.0000000001 秒。
然后您应该知道在声明本地字符串或任何对象时实际保留的内容:指针。实际上是一个 32/64 位“整数”,它保存实际找到字符串/对象的地址。因此该指令String updateWords = updateAuto();
不会创建新字符串,也不会将其复制到任何地方,所发生的只是 updateAuto() 函数返回一个指针(“整数”)并将 updateWords 设置为该值。这与写入一样快,int updateWords = 42
并且完全在堆栈甚至寄存器上完成,如果优化器愿意的话。
通常,您应该更多地担心可见性以及最方便/对您的应用程序产生最少错误的方法,而不是内部组织内存的方式。一次手动优化通常会使您的应用程序速度提高不超过 0.0000001%,其次,在保留内存时唯一愚蠢的做法是在这样的循环中毫无意义地执行此操作:
for (int i = 0; i < 1000; ++i) {
new MyReallyStupidMemoryWastingObject();
}
但即便如此,垃圾收集器也会优雅地处理(只要您不通过将所有这些指针放在列表或类似的东西中来保存所有这些指针)。
因此:如果可以简化代码,尤其是减少错误,请使用全局变量。示例是全局常量,如枚举或广泛使用的字符串关键字。否则使用本地或类本地变量并依靠 JVM 来正确执行操作。
一个常见的事情是给 JVM 一个使用提示,这个词final
。这允许 JVM 对此变量进行全面优化,甚至通过将其放入寄存器来完全删除它,因为它知道您永远不会更改它。
好的面向对象编程通常回避“全局”变量,而是倾向于将变量封装在对象中。有时这可以打破,比如当你有常量或其他东西时,但有一些模式。
也就是说,是的,如果您要创建多个线程,每个线程都有自己的updateWords
,那么您将创建更多对象,从而进行更多垃圾收集。但是,因为updateWords
是一个字符串,如果它在所有线程中设置为相同的值,Java 应该只创建一个String
,因为String
s 在 Java 中是文字。
只要线程没有被破坏,内存就会被消耗。查看字符串是否是您的类的属性(根据面向对象的设计)。
创建一个公共静态属性,并像这样在 Main Class 上初始化:
public class foo {
public static final string name = "Stack Overflow";
}