JavaScript 驱动的网站需要大量内存,但分析器没有给出提示
我试图找出为什么我的网站(使用 JavaScript,包括 jQuery 和 Google Maps API v2)单个选项卡需要超过 400 MB 的内存。
到目前为止我所做的:
- 在 Firefox 和 Chrome 中尝试过,同样的问题
- 在地图上创建路线之前检查 Chrome 的任务管理器,然后检查
- 之前:28 MB 选项卡进程内存(“私有内存”31 MB,“共享内存”13 MB)
- 之后:550 MB 选项卡进程内存(557 MB 私有内存,还有 13 MB 共享内存)
- 制作堆快照使用 Chrome 开发者工具
- 之前和之后的快照非常相似,都显示了大约 12 MB 的堆对象
所以这是我的问题:术语“私有/共享内存”到底意味着什么 - 它与堆栈变量有关吗?如何调试巨大的“私有”内存使用情况?不太关心我使用哪个浏览器进行调试。
编辑:不幸的是,当我在应用程序中创建 GMaps 路线时,出现了内存问题,这似乎无法在 IE 中正常工作 - 所以我有点局限于 Firefox/Chrome。
编辑2:我已经在没有任何工具的情况下找到了问题(如果有人知道的话,我仍然对工具感兴趣)。当我调用 someGPolylineInstance.insertVertex(0, point) 时会出现问题,其中 point 是“dblclick”事件中的纬度/经度点。每次我插入一个点(我注释掉了双击处理程序中发生的所有其他内容),Chrome 中的内存使用量就会增加约 1 MB。这可能是地图 API 的问题吗?
因此,由于我无法提供整个网站,因此我提取了一个显示问题的最小示例。目前我可以在 Chrome 10 上重现该问题。通过双击添加路线点会增加大约 0.5 MB 的内存使用量,而一次添加 50 个点需要更少的内存。请尝试告诉我您是否遇到同样的情况(只需以“file://”打开示例):
<html>
<head>
<script type="text/javascript" src="http://maps.google.com/maps?file=api&v=2&oe=utf-8&key=open_me_as_file_so_that_no_key_is_necessary"></script>
<script>
function init()
{
map = new GMap2(document.getElementById("map_canvas"), {mapTypes : [G_NORMAL_MAP],
draggableCursor : "crosshair"})
line = new GPolyline(new Array(), "#0090EE", 2, { clickable: false, geodesic: false })
map.addOverlay(line)
map.setCenter(new GLatLng(49, 9), 12)
map.addControl(new GLargeMapControl())
map.disableDoubleClickZoom()
GEvent.addListener(map, "dblclick",
function(overlay, clickedPoint)
{
if(!overlay)
line.insertVertex(0, clickedPoint)
}
)
}
lat = 49
lng = 9
function doSomething()
{
for(var i = 0; i < 50; ++i)
{
lat += 0.05
lng += 0.03
line.insertVertex(0, new GLatLng(lat, lng))
}
document.getElementById("debug").innerHTML = line.getVertexCount() + " points"
}
</script>
</head>
<body onload="init();">
<div id="map_canvas" style="width: 500px; height: 300px"></div>
<div id="debug"></div>
<button onclick="doSomething();">Add 50 points</button>
</body>
</html>
I'm trying to find out why my website (using JavaScript, including jQuery and the Google Maps API v2) needs more than 400 MB of memory for a single tab.
What I've done so far:
- Tried in both Firefox and Chrome, same problem
- Checked Chrome's task manager before creating a route on the map and afterwards
- Before: 28 MB tab process memory (31 MB in "private memory", 13 MB "shared memory")
- After: 550 MB tab process memory (557 MB in private memory, also 13 MB shared memory)
- Made heap snapshots with Chrome developer tools
- Snapshots before and after are very similar, both showing around 12 MB of heap objects
So here's my question: What exactly do the terms "private/shared memory" mean - does it have something to do with stack variables? How do I debug the huge "private" memory usage? Don't really care which browser I use for debugging.
Edit: Unfortunately, the memory problem arises when I create a GMaps route in my application, which doesn't seem to work correctly with IE - so I'm kind of restricted to Firefox/Chrome.
Edit 2: I have tracked down the problem without any tools (I'm still interested in tools if somebody knows one). The problem occurs when I call someGPolylineInstance.insertVertex(0, point)
where point is a lat/lng point from the "dblclick" event. Everytime I insert a point (I commented out everything else that happens in the double-click handler), memory usage goes up by ~1 MB in Chrome. Could this be a problem with the Maps API?
So as I can't put up my whole website, I extracted a minimal example which shows the problem. Currently I can reproduce the problem on Chrome 10. Adding a route point by double-clicking adds roughly 0.5 MB of memory usage, while adding 50 points at once needs less memory. Please try and tell me whether you experience the same (simply open the example as "file://"):
<html>
<head>
<script type="text/javascript" src="http://maps.google.com/maps?file=api&v=2&oe=utf-8&key=open_me_as_file_so_that_no_key_is_necessary"></script>
<script>
function init()
{
map = new GMap2(document.getElementById("map_canvas"), {mapTypes : [G_NORMAL_MAP],
draggableCursor : "crosshair"})
line = new GPolyline(new Array(), "#0090EE", 2, { clickable: false, geodesic: false })
map.addOverlay(line)
map.setCenter(new GLatLng(49, 9), 12)
map.addControl(new GLargeMapControl())
map.disableDoubleClickZoom()
GEvent.addListener(map, "dblclick",
function(overlay, clickedPoint)
{
if(!overlay)
line.insertVertex(0, clickedPoint)
}
)
}
lat = 49
lng = 9
function doSomething()
{
for(var i = 0; i < 50; ++i)
{
lat += 0.05
lng += 0.03
line.insertVertex(0, new GLatLng(lat, lng))
}
document.getElementById("debug").innerHTML = line.getVertexCount() + " points"
}
</script>
</head>
<body onload="init();">
<div id="map_canvas" style="width: 500px; height: 300px"></div>
<div id="debug"></div>
<button onclick="doSomething();">Add 50 points</button>
</body>
</html>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论