Anu*_*dha 0 java static garbage-collection jvm arraylist
我有以下代码似乎导致一些内存泄漏。每次用户执行操作时都会执行此代码片段(即 hasPermissions())。
因此,根据我的理解,由于 Map权限是静态对象,因此在hasPermission()方法 内创建的所有PermissionsList对象都引用全局静态对象(即Permissions);那么,是不是没有资格被垃圾收集呢?
以下是 Eclipse Memory Analyzer 工具中显示的泄漏嫌疑人的堆转储。当我导航到详细信息时,它显示带有以下代码片段的类。我发现 Java List.addAll()函数在内部创建LinkedList。我仍在尝试理解这里到底发生了什么。欣赏你的想法。
public class AccessManager {
private static Map <Integer, List> permissions;
public static void init()
{
//initiate permissions and add values
}
public static boolean hasPermissions(List<Integer> accessLevels, String action)
{
if (permissions == null)
init();
List permissionsList = null;
for (Integer a : accessLevels) {
if (permissionsList == null) {
permissionsList = permissions.get(a);
} else {
permissionsList.addAll(permissions.get(a));
}
}
if(permissionsList.contains(action)){
return true;
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
该代码已被严重破坏。在向List引用的对象添加新权限时permissions,该hasPermission方法不仅会造成内存泄漏,还可能导致后续访问检查被错误授予,这可能是一个相当严重的安全漏洞。
例如,如果permissions包含
| 钥匙 | 价值 |
|---|---|
| 1 | [A] |
| 2 | [b] |
并且您执行hasPermissions(Arrays.asList(1,2), "b"),permissions将更新为包含
| 钥匙 | 价值 |
|---|---|
| 1 | [一、二] |
| 2 | [b] |
导致后续调用hasPermissions(Arrays.asList(1), "b")返回 true。
此外,每次进一步调用都会hasPermissions(Arrays.asList(1,2), "b")导致 b 再次添加:
| 钥匙 | 价值 |
|---|---|
| 1 | [一、二、二] |
| 2 | [b] |
导致该列表变得越来越长,直到内存耗尽。这个充满重复项的极长列表会减慢访问检查速度,例如hasPermissions(Arrays.asList(1), "c")爬行。
哦,顺便说一下,init第一次调用时调用的惰性初始化hasPermissions不是线程安全的,但可能被多个线程访问。您应该声明权限(如果多个线程使用不安全,volatile甚至同步),或者在静态初始值设定项中调用。initinitinit
| 归档时间: |
|
| 查看次数: |
133 次 |
| 最近记录: |