【问题标题】:Regarding Java String Constant Pool关于Java字符串常量池
【发布时间】:2011-07-24 08:24:12
【问题描述】:

这是关于 Java 字符串常量池的。在我的一个程序中,我正在解密数据库的密码并将其存储在字符串中。我听说 Java 字符串将存储在常量池中,并且不会在 VM 重新启动或加载字符串退出的 ClassLoader 时被破坏。

如果是这种情况,我的密码将存储在字符串池中。我非常关心这个问题。有没有其他方法可以销毁这些文字或我能做的任何其他事情。

请就此提出建议,

问候, 晴天。

【问题讨论】:

    标签: java string passwords constants pool


    【解决方案1】:

    这仅适用于您已调用 intern() 方法的字符串文字和字符串。想一想:如果它适用于所有字符串,那么您将很快耗尽内存,例如处理具有不同(字符串)值的请求参数的 servlet 应用程序。

    【讨论】:

    • Java 1.8.20 引入了一个后台字符串重复数据删除功能,该功能非常类似于在没有任何人调用 intern() 的情况下让您的字符串 intern()...
    • 既然字符串,你调用intern() on,仍然会受到普通垃圾回收,没有理由处理所有字符串,好像intern()是在构造后应用的,应该提高内存要求.实际上,那时堆中的字符串实例会更少。但是,这样做会导致性能灾难……
    【解决方案2】:

    这里有几个不同的问题。首先,术语“常量池”是指类文件中非常特定的部分,用于字符串和数字文字,或者指从驻留在 JVM 中的类文件的这一部分生成的数据结构。密码不会存储在这里,除非它们是类文件的一部分。

    然而,一些 String 对象确实是通过 String 保留在整个程序中存储和共享的。任何字符串文字都会被自动实习,就像您调用 intern() 方法的任何字符串一样。不过,据我所知,没有其他字符串以这种方式存储,因此除非您自己自动实习保存密码的字符串,否则我认为您无需担心这一点。

    另一个需要注意的问题是,如果您不希望密码驻​​留在内存中,则可能需要小心垃圾收集,因为不再引用的 String 可能仍然在内存中。类似地,如果您使用某些字符串方法(例如子字符串)在字符串之间共享支持表示,您可以在使用完成后保留完整的密码字符串。

    如果您担心的是其他 Java 代码能够看到已被保留或仍然存在于内存中的旧密码,那么您无需担心。无法迭代或查看内部字符串池的元素,也无法打开 String 以查看其支持数组。

    【讨论】:

    • 从代码中找到这些字符串可能并不容易,但它们会在堆转储中。如果我试图攻击它们,我会尝试触发堆转储并尝试分离转储文件。
    【解决方案3】:

    老兄,使用字符串缓冲区来获取密码并进行(大概)字符串类型的操作。

    StringBuffer 将字符串存储为 char[],可以删除。或者被覆盖或者你有什么。 说StringBuffer.delete(0,StringBuffer.length());

    或者只是将 db 密码获取为 char[] 并直接使用它 - 但我认为 StringBuffer 方式(假设您已经使用 String 方法制作了所有代码)将是一个更容易的飞跃。

    【讨论】:

    • 如果您控制界面,char[] 非常棒。如果你必须调用一个将密码作为字符串的方法,迟早会创建一个字符串对象......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 2014-06-08
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多