Memory 内存在游戏中过度使用!框架方法调用

Memory 内存在游戏中过度使用!框架方法调用,memory,controller,playframework,Memory,Controller,Playframework,在我的一个控制器中,我有多个最终将以相同方式呈现的URL。例如,此方法扫描服务器所在的网络,缓存每个连接设备和每个侦听特定端口的设备的字符串表示,然后将该信息发送到另一个方法以呈现: public static void networkScan(String networkTarget, String port) { //These two lists will never have more than 256 total entries List<InetSocketAd

在我的一个控制器中,我有多个最终将以相同方式呈现的URL。例如,此方法扫描服务器所在的网络,缓存每个连接设备和每个侦听特定端口的设备的字符串表示,然后将该信息发送到另一个方法以呈现:

public static void networkScan(String networkTarget, String port)
{
    //These two lists will never have more than 256 total entries
    List<InetSocketAddress> listeningDevices;
    Map<String, String> allDevices;

    ...Logic for discovering network devices...

    //Store the results in a cache, for history preservation in the browser
    Cache.set(session.getId() + "listeningDevices", listeningDevices);
    Cache.set(session.getId() + "allDevices", allDevices);
    showScan(listeningDevices, allDevices);
}

public static void showScan(List<InetSocketAddress> listeningDevices, Map<String, String> allDevices)
{
    render(listeningDevices, allDevices);
}

public static void getCachedScan()
{
    List<InetSocketAddress> listeningDevices = (List<InetSocketAddress>)Cache.get(session.getId() + "listeningDevices");
    Map<String, String> allDevices = (Map<String, String>)Cache.get(session.getId() + "allDevices");
    if(listeningDevices == null)
        listeningDevices = new ArrayList<InetSocketAddress>();
    if(allDevices == null)
        allDevices = new TreeMap<String, String>();

    renderScan(listeningDevices, allDevices);
}
公共静态无效网络扫描(字符串网络目标,字符串端口)
{
//这两个列表的总条目数永远不会超过256个
列出列表设备;
映射所有设备;
…用于发现网络设备的逻辑。。。
//将结果存储在缓存中,以便在浏览器中保存历史记录
Cache.set(session.getId()+“listeningDevices”,listeningDevices);
Cache.set(session.getId()+“allDevices”,allDevices);
showScan(列表设备、所有设备);
}
公共静态void showScan(列出ListingDevices,映射所有设备)
{
呈现(列表设备、所有设备);
}
公共静态void getCachedScan()
{
List listeningDevices=(List)Cache.get(session.getId()+“listeningDevices”);
Map allDevices=(Map)Cache.get(session.getId()+“allDevices”);
如果(ListingDevices==null)
listeningDevices=new ArrayList();
如果(所有设备==null)
allDevices=新树映射();
renderScan(列表设备、所有设备);
}
这样做会导致执行一些奇怪的数组复制,最终占用无限内存。如果我将对
showScan()
的调用更改为简单的
render()
,并创建一个名为
networkScan.html
的视图,那么一切都正常,没有内存错误

基于不同的缓存设置,我还有其他几种方法也使用showScan。我不希望有很多视图本质上都是彼此的副本,因此我尝试只使用一个方法和一个对应的视图。

这不起作用:

   showScan(listeningDevices, allDevices);
}

public static void showScan(List<InetSocketAddress> listeningDevices, Map<String, String> allDevices)
{
showScan(列出设备,所有设备);
}
公共静态void showScan(列出ListingDevices,映射所有设备)
{
as play将ListingDevices+所有设备序列化为字符串,并尝试从中构建url

直接在networkScan()中呈现结果,或将内容存储在缓存中的特定键下 就像你已经做过的,然后做一些类似的事情

public static void networkScan(String networkTarget, String port)
{
    //These two lists will never have more than 256 total entries
    List<InetSocketAddress> listeningDevices;
    Map<String, String> allDevices;



       ...Logic for discovering network devices...

        //Store the results in a cache, for history preservation in the browser
        Cache.set(session.getId() + "listeningDevices", listeningDevices);
        Cache.set(session.getId() + "allDevices", allDevices);
        showScan(session.getId());
    }

    public static void showScan(String sessionId)
    {
    List<InetSocketAddress> listeningDevices = Cache.get(sessionId + "listeningDevices");
    Map<String, String> allDevices = Cache.get(sessionId + "allDevices");
        render(listeningDevices, allDevices);
    }
公共静态无效网络扫描(字符串网络目标,字符串端口)
{
//这两个列表的总条目数永远不会超过256个
列出列表设备;
映射所有设备;
…用于发现网络设备的逻辑。。。
//将结果存储在缓存中,以便在浏览器中保存历史记录
Cache.set(session.getId()+“listeningDevices”,listeningDevices);
Cache.set(session.getId()+“allDevices”,allDevices);
showScan(session.getId());
}
公共静态void showScan(字符串sessionId)
{
List listeningDevices=Cache.get(sessionId+“listeningDevices”);
Map allDevices=Cache.get(sessionId+“allDevices”);
呈现(列表设备、所有设备);
}

结果表明,调用操作方法会创建重定向事件,从而导致各种对象复制到URL。我仍然不明白这是如何迅速发展到使用超过千兆字节的内存来处理一组字符串的,这些字符串的编号很少超过100,也从未超过256,但我找到了一种避免重定向事件的方法

正如我在Google Groups上的一篇文章中被指示的那样,我在showScan方法上使用了
@Util
拦截器:

@Util
public static void showScan(List<InetSocketAddress> listeningDevices, Map<String, String> allDevices)
{
    renderTemplate("Admin/showScan.html", listeningDevices, allDevices);
}
@Util
公共静态void showScan(列出ListingDevices,映射所有设备)
{
renderTemplate(“Admin/showScan.html”、ListingDevices、allDevices);
}

不幸的是,用
@Util
标记一个方法会使它使用调用方法的模板,但是对
renderTemplate()的调用
允许我使用我指定的单一模板。

我认为你的答案有效,但我最终选择了另一种解决方案。
@Util
拦截器在调用操作方法时阻止重定向事件。这将覆盖我的所有基础,无论我是否想使用缓存。它没有很好的文档,但我得到了e当我在谷歌集团上提问时,我的回答是: