字符串是不可变的。当我声明:
String a = "abc";
String a1 = "abc";
两个对象都指向同一位置。那么,如何从字符串池中销毁该“ abc”引用呢?
我的用例是,我正在开发内存更少的硬件应用程序,为此,我需要从字符串池中清除引用以节省内存。
不,通常您不能手动“从Java中的字符串池中破坏引用”。
我想为什么要定位它的主要原因是为了避免内存不足错误。在Java中,有6天时间,所有被嵌入的字符串都存储在PermGen中,PermGen是堆的固定大小部分,主要用于存储加载的类和字符串池。除了显式的固定字符串外,PermGen字符串池还包含程序中先前使用的所有文字字符串。Java
6中字符串池的最大问题是它的位置– PermGen。 PermGen 具有固定大小,无法在运行时扩展。您可以使用 -XX:MaxPermSize
= N
选项进行设置。这将导致内存泄漏和内存不足错误。
在Java 7中-字符串池已重定位到 堆 。这意味着您不再受限于单独的固定大小的存储区。现在,所有字符串和大多数其他普通对象一样都位于堆中。
您还可以通过配置 -XX:StringTableSize = N来 增加字符串池的大小。如果不确定字符串池的使用情况,请尝试 -XX:+
PrintStringTableStatistics
JVM参数。程序终止时,它将打印您的字符串池使用情况。
在JDK中,还有一个 名为jmap的工具 ,可用于在您的应用程序中查找许多内联字符串。
jmap -heap process_id
例如:
jmap -heap 18974
与其他输出一起,此命令还输出内联字符串的数量及其所占的空间“ xxxxxx内联字符串占xxxxxx字节” 。
字符串池中对象的垃圾回收规则与其他 字符串或任何其他对象的 规则相同
。但是事实上,与String文字相对应的String对象通常总是可以访问的,因为在使用该文字的每种方法的代码中都有对字符串对象的隐式引用,因此通常它们不是垃圾回收的候选对象。然而,这并非总是如此。如果文字是在动态加载的类中定义的(例如,使用Class.forName(…)),则可以安排该类的卸载。如果发生这种情况,则文字的String对象将无法访问,并且在包含内部String的堆被GC回收时将被回收。
问题内容: 我在接受以下采访时遇到了这个问题: 如何在Java中销毁对象? 答案应该是e? 如果e不在那里怎么办?然后 ?显然,c不是答案。a和b将为整个应用程序执行gc(问题需要一个对象)。我认为这是d,因为finalize()刚好在gc之前被调用(但是是否有必要在finalize gc之后被调用?)还是我错了?您必须在那里回答这个问题吗? 问题答案: 答案E是正确答案。如果E不存在,您将很快用
问题内容: 我对垃圾收集器在Java中的工作方式有一个大致的了解,但是我销毁对象的原因不是因为我关心释放内存,而是因为功能。我可以用一个例子更好地解释: 假设我正在制作涉及金钱的游戏。当某人从地面上捡起一个物体时,我想调用该物体的方法,该方法涉及为该人的钱包添加一个值。 之后发现,我不希望别人能够把它捡起来。换句话说,我不希望自己或任何其他程序能够不经意间拨打电话: 因此,在Bob拿起钱后,它的价
输出:2 请告诉我如何找到上述(searchValue)元素的索引。
我正在使用Java8。我不是java专家(自从10年前上大学以来就没有研究过java) 我创建了一个ScriptEngine的实例(Nashorn,如果有必要的话)。我用它来评估几个javascript文件。 这个脚本在自己的小javascript世界里运行得非常愉快。我喜欢。 我还运行了一个文件系统监视服务,以防我的一些java脚本被修改。当它们被修改时,我创建一个新的ScriptEngine,
问题内容: 我对Java中的StringPool感到困惑。我在阅读Java中的String一章时遇到了这个问题。用外行的术语,请帮助我了解StringPool的实际作用。 问题答案: 打印(即使我们不使用方法:比较字符串的正确方法) 当编译器优化你的字符串文字时,它会看到两者s和t具有相同的值,因此你只需要一个字符串对象。这是安全的,因为在中是不可变的。 结果,两者和都t指向同一个对象,节省了一些
问题内容: 如何获得“ E”输出而不是69? Golang是否具有将字符转换为字节,反之亦然的功能? 问题答案: 解释的字符串文字是使用单个字符的UTF-8编码(可能是多字节)在双引号“”之间的字符序列。在UTF-8中,ASCII字符是单字节,对应于前128个Unicode字符。字符串的行为就像字节片。符文是标识Unicode代码点的整数值。因此, 输出: 读: 进入转换的编程语言规范部分。 Go